Avatar billede riishoj Nybegynder
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

%>
Avatar billede ffsoft Praktikant
12. oktober 2006 - 13:37 #1
Du kan bruge replace() til erstatte dobbelte ;; med et enkelt ;


strTxt = replace("" & strTxt & "",";;",";")

.
Avatar billede riishoj Nybegynder
12. oktober 2006 - 14:08 #2
Kan du også fortælle, hvor i scriptet jeg skal sætte det ind?
Avatar billede ffsoft Praktikant
12. oktober 2006 - 20:05 #3
Tjah, det er jo en ordentlig dynge kode du remser op
men lige inden resultatfilen bliver gemt ville være et godt
bud:

fle.write DataString
DataString= replace("" & DataString & "",";;",";")
fle.close

.
Avatar billede ffsoft Praktikant
12. oktober 2006 - 20:07 #4
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.
Avatar billede riishoj Nybegynder
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="&quot;">&quot;</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

%>
Avatar billede riishoj Nybegynder
12. oktober 2006 - 22:02 #6
Linje 111 =    URS.Update
Avatar billede riishoj Nybegynder
13. oktober 2006 - 13:57 #7
Jeg har løst problemet, så jeg ikke behøver at fjerne de dobbelte semikolonner, men du skal alligevel have dine point:)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester