12. oktober 2006 - 13:05
Der er
6 kommentarer og
1 løsning
Fjerne tegn i text-fil
Jeg har en semikolonsepareret tekstfil som jeg skal have puttet i en database. Problemet er, at når jeg modtager tekstfilen, så indeholder den en tom kolonne, dvs. der er 2 semikolonner mellem 2 data.
Eks. Peter;;Jensen;Aalborg
Jeg skal altså have fjernet det ene semikolon mellem Peter og Jensen. Det kan jeg selvfølgelig klare i hvilket som helst tekstbehandllingsprogram, men meningen er, at det skal klares automatisk, inden filen bliver uploaded til en database. Nedenstående script uploader filen til serveren med fso, - fjernelsen af semikolon skal altså ske inden dette script eksekveres. Er der nogen som forstår hvad jeg mener, og som har en løsning på problemet?
Her er upload scrptet:
<%
option explicit
' used to track various positions
dim PosB, PosBBound, PosEBound, PosEHead, PosBFld, PosEFld
' these handle the data
dim Boundary, BBoundary, PartBHeader, PartAHeader, PartContent, PartContent2, Binary
' for writing and converting
dim fso, fle, rst, DataString, FileName
' various other
dim I, Length, ContType, PartName, LastPart, BCrlf, PartContentLength
' ado constants
const adLongVarBinary = 205
const adLongVarchar = 201
' must be submitted using POST
If Request.ServerVariables("REQUEST_METHOD") = "POST" Then
ContType = Request.ServerVariables("HTTP_Content_Type")
' must be "multipart/form-data"
If LCase(Left(ContType, 19)) = "multipart/form-data" Then
PosB = InStr(LCase(ContType), "boundary=") 'get boundary
If PosB > 0 Then Boundary = Mid(ContType, PosB + 9) 'we have one
'bugfix IE5.01 - double header
PosB = InStr(LCase(ContType), "boundary=")
If PosB > 0 then
PosB = InStr(Boundary, ",")
If PosB > 0 Then Boundary = Left(Boundary, PosB - 1)
end if
Length = CLng(Request.ServerVariables("HTTP_Content_Length")) 'Get Content-Length header
End If
If Length > 0 And Boundary <> "" Then
Boundary = "--" & Boundary
' get request, binary
Binary = Request.BinaryRead(Length)
' convert boundry to binary
For I=1 to len(Boundary)
BBoundary = BBoundary & ChrB(Asc(Mid(Boundary,I,1)))
Next
' binary crlf
BCrlf = ChrB(Asc(vbCr)) & ChrB(Asc(vbLf))
' get begin and end of first boundary
PosBBound = InStrB(Binary, BBoundary)
PosEBound = InStrB(PosBBound + LenB(BBoundary), Binary, BBoundary, 0)
' keep doing until we had them all
Do While (PosBBound > 0 And PosEBound > 0)
' get position of the end of the header
PosEHead = InStrB(PosBBound + LenB(BBoundary), Binary, BCrlf & BCrlf)
' get content of header and convert to string
PartBHeader = MidB(Binary, PosBBound + LenB(BBoundary) + 2, PosEHead - PosBBound - LenB(BBoundary) - 2)
PartAHeader = ""
For I=1 to lenb(PartBHeader)
PartAHeader = PartAHeader & Chr(AscB(MidB(PartBHeader,I,1)))
Next
' make sure we end it with ;
If Right(PartAHeader,1) <> ";" Then PartAHeader = PartAHeader & ";"
' get content of this part
PartContent = MidB(Binary, PosEHead + 4, PosEBound - (PosEHead + 4) - 2)
' get name of part
PosBFld = Instr(lcase(PartAHeader),"name=")
If PosBFld > 0 Then
' name found
PosEFld = Instr(PosBFld,lcase(PartAHeader),";")
If PosEFld > 0 Then
' well-formed name header
PartName = Mid(PartAHeader,PosBFld+5,PosEFld-PosBFld-5)
end if
' chop of leading and trailing "'s
Do Until Left(PartName,1) <> """"
PartName = Mid(PartName,2)
Loop
Do Until Right(PartName,1) <> """"
PartName = Left(PartName,Len(PartName)-1)
Loop
end if
' get file name of part (if any)
PosBFld = Instr(lcase(PartAHeader),"filename=""")
If PosBFld > 0 Then
' content header found
PosEFld = Instr(PosBFld + 10,lcase(PartAHeader),"""")
If PosEFld > 0 Then
' well-formed content header
FileName = Mid(PartAHeader,PosBFld+10,PosEFld-PosBFld-10)
end if
' chop of leading and trailing "'s
Do Until Left(FileName,1) <> """"
FileName = Mid(FileName,2)
Loop
Do Until Right(FileName,1) <> """"
FileName = Left(FileName,Len(FileName)-1)
Loop
Else
FileName = ""
end if
' do conversion of binary to regular data
' at the end, datastring will contain 'readable' data
' is this wide-byte binary data?
if vartype(PartContent) = 8 then
' need to do some conversion
Set rst = CreateObject("ADODB.Recordset")
PartContentLength = LenB(PartContent)
if PartContentLength > 0 then
' data, so add to recordset to speed up conversion
rst.Fields.Append "data", adLongVarBinary, PartContentLength
rst.Open
rst.AddNew
rst("data").AppendChunk PartContent & ChrB(0)
rst.Update
PartContent2 = rst("data").GetChunk(PartContentLength)
rst.close
set rst = nothing
else
' no data?
PartContent2 = ChrB(0)
End If
else
' no need for conversion
PartContent2 = PartContent
end if
PartContentLength = LenB(PartContent2)
if PartContentLength > 0 then
' we have data to convert
Set rst = CreateObject("ADODB.Recordset")
rst.Fields.Append "data", adLongVarChar, PartContentLength
rst.Open
rst.AddNew
rst("data").AppendChunk PartContent2
rst.Update
DataString = rst("data")
rst.close
set rst = nothing
Else
' nothing to convert
dataString = ""
End If
' conversion has been done, now what to do with it
If FileName <> "" Then
' we have a file, let's save it to disk
FileName = Mid(Filename,InstrRev(FileName,"\")+1)
' open a file (textstream)
set fso = Server.CreateObject("Scripting.Filesystemobject")
set fle = fso.CreateTextFile(server.MapPath("/Importer/Incomming/" & FileName))
' write the data
fle.write DataString
fle.close
' cleanup
set fle = nothing
set fso = nothing
' give notification
'Response.Write "<BR>Uploaded file " & Partname & " - " & FileName & "(" & Len(Datastring) & " bytes)"
Response.Redirect("Analyse.asp?File=" & FileName)
else
' some other type of field, let's just output this
'Response.Write "<BR>Form field: " & Partname & " - " & Datastring
End If
LastPart = MidB(Binary, PosEBound + LenB(BBoundary), 2)
If LastPart = ChrB(Asc("-")) & ChrB(Asc("-")) Then
' don't look for others
PosBBound = 0
PosEBound = 0
else
' look for others
PosBBound = PosEBound
PosEBound = InStrB(PosBBound + LenB(BBoundary), Binary, BBoundary)
End If
loop
'Response.Write "<P>End of form input, all fields processed"
else
Response.Write "<P>Invalid or empty request, no fields processed. Make sure that the content type is multipart/form-data"
end if
else
Response.Write "<P>Form must be submitted using the POST method"
end if
%>
12. oktober 2006 - 22:00
#5
Nej, det virker desværre ikke.
"Men grunden til at der er dobbelt ;; er vel at der skal være
plads til et mellemnavn så det er ikke sikkert at det er en god
ide at pille ved det."
Hvis jeg ikke fjerner de dobbelte "" får jeg en fejl i et andet scrip
Microsoft JET Database Engine error '80040e21'
Field 'tblIPDetail.fldFieldName' cannot be a zero-length string.
/Importer/Step2.asp, line 111
step2.asp ser sådan ud: (og som jeg slet ikke kan overskue)
<!-- #include virtual="/Importer/OpenDB.asp"-->
<%
Set RS = Server.CreateObject("ADODB.RecordSet")
With RS
.CursorLocation = adUseServer
.Open "SELECT * FROM tblImportProfile WHERE fldIPID = " & Request("IPID"), CONN, adOpenKeyset, adLockOptimistic
End With
If Request.Form("Action") <> "" Then
' Open up a connection to tblIPDetail since we will probably want to write to it
Set URS = Server.CreateObject("ADODB.RecordSet")
With URS
.CursorLocation = adUseServer
.Open "SELECT * FROM tblIPDetail WHERE fldIPID = " & Request.Form("IPID"), CONN, adOpenKeyset, adLockOptimistic
End With
If Not URS.Eof Then conn.execute("DELETE * FROM tblIPDetail WHERE fldIPID = " & Request("IPID"))
If Trim(RS("fldFixOrDelim")) = "F" Then
'We are dealing with a Fixed Width dataset. Store Col Width Data in tblIPDetail
StartRow = 0
FieldNum = 0
'Open the file and drag in 1 line to test
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.OpenTextFile(Server.MapPath("/Importer/Incomming/" & Request("File")), 1, 0)
TestLine = a.ReadLine
a.Close
Set a = Nothing
Set fs = Nothing
Cols = Split(Request("Cols"), ",")
For Each FieldEnd In Cols
URS.AddNew
URS.Fields("fldIPID").value = Request.Form("IPID")
URS.Fields("fldFieldLoc").value = FieldNum
URS.Fields("fldStart").value = StartRow
URS.Fields("fldWidth").value = FieldEnd-StartRow
If Request.Form("FirstRowContainsName") = "TRUE" Then
If Mid(CStr(Replace(FieldNames, vbCrLf, "")), CInt(URS("fldStart"))+1, CInt(URS("fldWidth"))) <> "" Then
URS.Fields("fldFieldName").value = Trim(Mid(FieldNames, CInt(URS("fldStart"))+1, CInt(URS("fldWidth"))))
End If
End If
URS.Update
'Update the Start Position by adding StartRow and FieldLength
StartRow = FieldEnd
FieldNum=FieldNum+1
Next
' But thats not all... we must remember now to catch the last field on the end
FieldLength = Len(TestLine)-StartRow
URS.AddNew
URS.Fields("fldIPID").value = Request.Form("IPID")
URS.Fields("fldFieldLoc").value = FieldNum
URS.Fields("fldStart").value = StartRow
URS.Fields("fldWidth").value = FieldLength
If Request.Form("FirstRowContainsName") = "TRUE" Then
If Mid(CStr(Replace(FieldNames, vbCrLf, "")), CInt(URS("fldStart"))+1, CInt(URS("fldWidth"))) <> "" Then
URS.Fields("fldFieldName").value = Trim(Mid(FieldNames, CInt(URS("fldStart"))+1, CInt(URS("fldWidth"))))
End If
End If
URS.Update
Else
' Safe to assume Delimited so store the details about delimiters in tblImportProfile
' We will store delimiters as ASCI values just incase some odd chars ar used
' We assume that new records will always start on a new line
If Request.Form("TextQualifier") <> "" Then
If Request.Form("TextQualifier") = "{Other}" Then
RS.Fields("fldTextQualifier").value = ASC(Request.Form("UserTextQualifier"))
Else
RS.Fields("fldTextQualifier").value = ASC(Request.Form("TextQualifier"))
End If
End If
If Request.Form("FieldDelim") = "{Other}" Then
RS.Fields("fldFieldDelim").value = ASC(Request.Form("UserFieldDelim"))
Else
RS.Fields("fldFieldDelim").value = ASC(Request.Form("FieldDelim"))
End If
RS.Update
' Next we need to put some blank records into the Detail Table
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.OpenTextFile(Server.MapPath("/Importer/Incomming/" & Request("File")), 1, 0)
FieldNames = CStr(a.ReadLine)
a.Close
URS.Requery
DataFields = Split(FieldNames, Chr(RS("fldFieldDelim")))
For i=0 To UBound(DataFields)
URS.AddNew
If RS("fldTextQualifier") > 0 Then
FieldName = Trim(Split(DataFields(i), Chr(RS("fldTextQualifier")))(1))
Else
FieldName = Trim(DataFields(i))
End If
URS.Fields("fldIPID").value = Request.Form("IPID")
URS.Fields("fldFieldLoc").value = i
If Request.Form("FirstRowContainsName") = "TRUE" Then
URS.Fields("fldFieldLoc").value = i
If RS("fldTextQualifier") > 0 Then
FieldName = Trim(Split(DataFields(i), Chr(RS("fldTextQualifier")))(1))
Else
FieldName = Trim(DataFields(i))
End If
URS.Fields("fldFieldName").value = FieldName
End If
URS.Update
Next
End If
If Request.Form("FirstRowContainsName") = "TRUE" Then
' Update the DB So we have a record of it
RS.Fields("fldFirstLineName").value = True
RS.Update
RS.Requery
End If
' Now We just need to redirect to appropriate pages. Use JS to update the different frames
%>
<html>
<head>
<title></title>
<script language="JavaScript">
parent.Main.location='Step3.asp?IPID=<%= Request("IPID") %>&File=<%= Request("File") %>';
parent.Preview.location='Preview.asp?IPID=<%= Request("IPID") %>&File=<%= Request("File") %>';
</script>
</head>
<body bgcolor="#CCCCCC" text="#000000">
</body>
</html>
<%
Else
' Show the user forms
If Trim(RS("fldFixOrDelim")) = "F" Then
' Give some basic instruction on what to do and add little tick box. Dont forget the hidden form elements
%>
<html>
<head>
<title></title>
<script language="JavaScript">
<!--
function toggleFirst() {
if(document.form1.FirstRowContainsName.checked==true) {
parent.Preview.FWidthForm.FirstRowContainsName.value = 'TRUE';
} else {
parent.Preview.FWidthForm.FirstRowContainsName.value = 'FALSE';
}
}
//-->
</script>
</head>
<body bgcolor="#CCCCCC" text="#000000">
<form name="form1" method="post" action="Step2.asp">
<input type="hidden" name="IPID" value="<%= Request("IPID") %>">
<input type="hidden" name="File" value="<%= Request("File") %>">
<div align="center">
<p>First Row Contains Field Names
<input type="checkbox" name="FirstRowContainsName" value="TRUE" onClick="toggleFirst();">
</p>
<input type="button" name=" Next >> " value="Button" onClick="parent.Preview.calcandsubmit();">
</div>
</form>
</body>
</html>
<%
Else
' Give the User a Form about delimiters etc. With preview button which posts it to the preview pane
%>
<html>
<head>
<title></title>
<script language="JavaScript">
function previewData() {
document.Step2.action="Preview.asp";
document.Step2.Preview.value="TRUE";
document.Step2.target="Preview";
document.Step2.submit();
// Now reset it all back so that if the next button is pressed it works
document.Step2.action="Step2.asp";
document.Step2.Preview.value="FALSE";
document.Step2.target="Main";
}
</script>
</head>
<body bgcolor="#CCCCCC" text="#000000">
<form name="Step2" method="POST" action="Step2.asp">
<input type="hidden" name="IPID" value="<%= Request("IPID") %>">
<input type="hidden" name="File" value="<%= Request("File") %>">
<input type="hidden" name="Preview" value="FALSE">
<table border="0" cellspacing="4" cellpadding="6" align="center">
<tr>
<td align="center" valign="middle" colspan="2">
<table width="100%" border="1" cellspacing="0" cellpadding="0">
<tr>
<td>
<table width="100%" border="0" cellspacing="5" cellpadding="5">
<tr>
<td>
<input type="radio" name="FieldDelim" value=" ">
Tab </td>
<td>
<input type="radio" name="FieldDelim" value=";">
Semicolon </td>
<td>
<input type="radio" name="FieldDelim" value=",">
Comma </td>
<td>
<input type="radio" name="FieldDelim" value=" ">
Space </td>
<td>
<input type="radio" name="FieldDelim" value="{Other}">
Other:
<input type="text" name="UserFieldDelim" size="3">
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="left" valign="middle">
<input type="checkbox" name="FirstRowContainsName" value="TRUE">
First Row Contains Field Names </td>
<td align="right" valign="middle">Text Qualifier
<select name="TextQualifier">
<option value=""">"</option>
<option value="'">'</option>
<option value="">{None}</option>
<option value="{Other}">{Other}</option>
</select>
other:
<input type="text" name="UserTextQualifier" size="3">
</td>
</tr>
</table>
<BR>
<div align="center"><input type="submit" name="Action" value=" Next >> ">
<input type="button" name="Button" value=" Preview " onClick="previewData()">
</div>
</form>
</body>
</html>
<%
End If
End If
RS.Update
RS.Close
Set RS = Nothing
%>