สอบถามการ Import text file ที่มีจำนวนคอลัมภ์ไม่แน่
กระทู้เก่าบอร์ด อ.Yeadram

 1,557   7
URL.หัวข้อ / URL
สอบถามการ Import text file ที่มีจำนวนคอลัมภ์ไม่แน่

ผมขอสอบถามเรื่องการ Import text file ครับ
ตอนนี้ผมมี text file ที่ต้อง Import ทุกวัน
โดยที่ table มีจำนวน 11 column
แต่ text file ที่ได้มาแต่ละวันจะมีข้อมูลที่ไม่แน่นอนอาจมี 3 - 11 Column ได้
เช่น
Table มี Column ชื่อ 1 - 11
Text file แต่ละวันจะไม่เหมือนกัน
วันที่ 1 มี Column
1 ,2 ,4 ,5 ,11
วันที่ 2 มี Column
1 ,7 ,8 ,11
วันที่ 3 มี Column
1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11

โดยรูปแบบ text file จะคั่น Column ด้วย tab ครับมีแถวแรกเป็นชื่อ column

คำถามครับ :
ถ้าผมต้องการให้ import ข้อมูลกรณีนี้จะทำได้ยังไงบ้างครับ ผมลองสร้าง macro โดยใช้ transfertext แล้ว พบว่าถ้าวันไหนมี Column น้อยข้อมูลจะเลื่อนมาไม่ตรงกับชื่อ Column ครับ

พอจะมีวิธีการ Import ข้อมูลลักษณะนี้มั้ยครับ

รบกวนด้วยครับ

7 Reply in this Topic. Dispaly 1 pages and you are on page number 1

1 @R19313
import เข้ามาโดยมีโครงสร้างตาม text file ก่อน จากนั้นสร้าง qry append เลือก field ที่เหมือนกัน เข้าไปใน table ที่ต้องการ

***การ import data text file ข้อมูลต้องมีโครงสร้างที่แน่นอน จึงจะทำการ import data แบบซ้ำๆได้ ถ้าเป็นกรณีต้องทำตามคำแนะนำขั้นต้น
2 @R19315
เห็นบอกว่าแถวแรกเป็นชื่อ column แล้วตอน import ได้เลือกตัวเลือก First row contains field name หรือยังครับ นอกจากนี้ เราก็สามารถเลือกได้ว่าให้ใช้ Tab เป็น column/field delimiter ด้วยครับ
3 @R19319
เลือกครับอาจารย์
ปัญหาตอนนี้คือเป็นงานที่ต้องทำทุกวันครับถ้าให้ import แบบ manual คนใช้งานน่าจะงงครับ
ก่อนหน้านี้มีโปรแกรมที่คนเก่าเคยพัฒนาไว้ครับด้วย VB

ตัวโค้ดประมาณนี้ครับ (มีส่วนที่ประกาศ connection อีก แต่คร่าวๆคือประมาณนี้ครับ)
        Dim srOutstdDep As StreamReader
        Dim lsOutstdDep As String
        Dim liTotRec As Integer
        Dim ldAmount As Decimal
        Dim ldVAT As Decimal
        Dim i As Integer
        Dim lsAccountNo As String
        Dim ldAccountNo As Decimal
        Dim ld15 As Decimal
        Dim ld16 As Decimal
        Dim ld21 As Decimal
        Dim ld22 As Decimal
        Dim ld23 As Decimal
        Dim ld24 As Decimal
        Dim ld41 As Decimal
        Dim ld51 As Decimal
        Dim ld52 As Decimal
        Dim lsSeq(20) As String
        Dim lsFilePath() As String = Split(fuOutstandingDeposit.PostedFile.FileName, "\")
        Dim lsFileName As String = lsFilePath(UBound(lsFilePath))
        Dim lsFile As String

        btnUpload.Enabled = False
        btnCancel.Enabled = False
        ' lsFile = fuOutstandingDeposit.PostedFile.FileName
        lsFile = Server.MapPath("upload\" & lsFileName)
        fuOutstandingDeposit.PostedFile.SaveAs(lsFile)

        srOutstdDep = New StreamReader(lsFile, Encoding.GetEncoding(874))
        lsOutstdDep = srOutstdDep.ReadLine
        lsOutstdDep = Replace(lsOutstdDep, Chr(34), "")
        Dim lsOutstdDeposit() As String = lsOutstdDep.Split(vbTab)
        If lsOutstdDeposit(0) = "AccountNo." Then
            lsSeq(0) = ""
            For i = 1 To lsOutstdDeposit.Length - 1
               Select Case lsOutstdDeposit(i)
                    Case 15
                        lsSeq(i) = "15"
                    Case 16
                        lsSeq(i) = "16"
                    Case 21
                        lsSeq(i) = "21"
                    Case 22
                        lsSeq(i) = "22"
                    Case 23
                        lsSeq(i) = "23"
                    Case 24
                        lsSeq(i) = "24"
                    Case 41
                        lsSeq(i) = "41"
                    Case 51
                        lsSeq(i) = "51"
                    Case 52
                        lsSeq(i) = "52"
               End Select
            Next
            srOutstdDep.Close()
            srOutstdDep = New StreamReader(lsFile, Encoding.GetEncoding(874))
            lsOutstdDep = srOutstdDep.ReadLine
            Do While srOutstdDep.Peek <> -1
               lsOutstdDep = srOutstdDep.ReadLine
               lsOutstdDep = Replace(lsOutstdDep, Chr(34), "")
               If Len(lsOutstdDep) > 10 Then
                    Dim lsOutstdDepCount() As String = lsOutstdDep.Split(vbTab)
                    If Decimal.TryParse(lsOutstdDepCount(0), ldAccountNo) Then
                        liTotRec = liTotRec + 1
                        If Decimal.TryParse(lsOutstdDepCount(1), ldAmount) Then _
                            ldAmount = ldAmount + CDec(lsOutstdDepCount(1))
                        If Decimal.TryParse(lsOutstdDepCount(2), ldVAT) Then _
                            ldVAT = ldVAT + CDec(lsOutstdDepCount(2))
                    End If 'If Decimal.TryParse(lsOutstdDep(0), liHPAccountNo) Then
               End If 'If Len(lsOutstdDep) > 50 Then
            Loop 'Do While srOutstdDep.Peek <> -1
            srOutstdDep.Close()
            Dim lbHistory As Boolean = ImportHistoryDB.ImportHistory_GetData(liTotRec, ldAmount, ldVAT)
            i = 0
            ld15 = 0
            ld16 = 0
            ld21 = 0
            ld22 = 0
            ld23 = 0
            ld24 = 0
            ld41 = 0
            ld51 = 0
            ld52 = 0
            lbHistory = False
            If lbHistory = False Then
               ImportHistoryDB.ImportHistory_Add(liTotRec, ldAmount, ldVAT, lsFile)
               srOutstdDep = New StreamReader(lsFile, Encoding.GetEncoding(874))
               lsOutstdDep = srOutstdDep.ReadLine
               Do While srOutstdDep.Peek <> -1
                    lsOutstdDep = srOutstdDep.ReadLine
                    If Len(lsOutstdDep) > 10 Then
                        Dim lsOutstdDepTxt() As String = lsOutstdDep.Split(vbTab)
                        If Decimal.TryParse(Trim(lsOutstdDepTxt(0)), ldAccountNo) Then
                            lsAccountNo = lsOutstdDepTxt(0)
                            For i = 1 To lsOutstdDepTxt.Length - 1
                                Select Case lsSeq(i)
                                    Case "15"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld15) Then
                                           ld15 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld15 = 0
                                        End If
                                    Case "16"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld16) Then
                                           ld16 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld16 = 0
                                        End If
                                    Case "21"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld21) Then
                                           ld21 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld21 = 0
                                        End If
                                    Case "22"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld22) Then
                                           ld22 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld22 = 0
                                        End If
                                    Case "23"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld23) Then
                                           ld23 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld23 = 0
                                        End If
                                    Case "24"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld24) Then
                                           ld24 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld24 = 0
                                        End If
                                    Case "41"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld41) Then
                                           ld41 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld41 = 0
                                        End If
                                    Case "51"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld51) Then
                                           ld51 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld51 = 0
                                        End If
                                    Case "52"
                                        If Decimal.TryParse(lsOutstdDepTxt(i), ld52) Then
                                           ld52 = CDec(lsOutstdDepTxt(i))
                                        Else
                                           ld52 = 0
                                        End If
                                End Select
                            Next
                            Dim dtOutstandingDepositDetail As DataTable = OutstandingDepositDetailDB.OutstandingDepositDetail_GetData(CDate(txtImportDate.Text), lsAccountNo)
                            If Not dtOutstandingDepositDetail Is Nothing Then
                                If dtOutstandingDepositDetail.Rows.Count > 0 Then
                                    OutstandingDepositDetailDB.OutstandingDepositDetail_Del(CDate(txtImportDate.Text), lsAccountNo)
                                End If
                            End If
                            OutstandingDepositDetailDB.OutstandingDepositDetail_Add(CDate(txtImportDate.Text), lsAccountNo, ld15, ld16, ld21, ld22, ld23, ld24, ld41, ld51, ld52)
                        End If 'If Integer.TryParse(Trim(lsOutstdDepTxt(2)), liClientNo) Then
                    End If 'If Len(lsOutstdDep) > 10 Then
               Loop 'Do While srOutstdDep.Peek <> -1
               Dim dtDetail As DataTable = OutstandingDepositDetailDB.OutstandingDepositDetail_GetDataByDate(CDate(txtImportDate.Text), CDate(txtImportDate.Text))
              
               OutstandingDepositSummaryDB.OutstandingDepositSummary_UpdOutstandingDate(CDate(txtImportDate.Text))
               srOutstdDep.Close()
               Response.Write("alert('Import file complete.');")
               UserLogDB.UserLog_Add(Session("CompanyID"), Session("UserID"), "Import Outstanding Deposit Data Text File : " & lsFile)
            Else
               liTotRec = 0
               ldAmount = 0
               ldVAT = 0
               Response.Write("alert('Duplicate file.');")
            End If 'If Not drImportHistory.Read Then
        End If 'If Integer.TryParse(Trim(lsOutstdDepTxt(2)), liClientNo) Then


ตอนนี้กำลังลองแกะโค้ดมาใช้กับ Access อยู่ครับเลยมาสอบถามกับอ.ในนี้ครับเผื่อทาง Access มีวิธีที่สามารถทำได้โดยใช้ Query & Macro ได้เลยครับ

ตอนนี้ที่ทำทำได้ถึงอ่าน string จาก text file ได้แล้วครับแต่ยัง Split ไฟล์ไม่ได้
*ใช้ streamreader ไม่ได้เลยเปลี่ยนเป็น open for input แทนครับ
Dim intFile As Integer
Dim strFile As String
Dim strIn As String
Dim strOut As String
strOut = vbNullString
intFile = FreeFile()
strFile = "C:\Konkanokk\Loan Valuation\Import\OutstandingDepositbyAccount.txt"

    Open strFile For Input As #intFile
    MsgBox intFile
    
    Line Input #intFile, strIn
    Dim lsOutstdDeposit() As String

อาจารย์ท่านไหนเคยมีทำเคสแบบนี้ไว้รบกวนขอความรู้หน่อยครับ
4 @R19322
เราใช้คำสั่ง docmd.TransferText ,,"ชื่อเทเบิล", "พาธและชื่อเท็กซ์ไฟล์",-1 แค่นี้ก็ทำได้แล้วครับ แม้ว่าจะมีคอลัมน์ไม่ครบก็ตาม

หมายเหตุ : ผมไม่แน่ใจว่าเครื่องผมมีปัญหาอะไรหรือเปล่า ผมทดลองโดยใช้ Tab Delimited มันจะเกิด error ในการ import    แต่ถ้าใช้ Comma Delimited จะทำงานได้โดยไม่มีปัญหา ลองไปทดลองดูนะครับ
5 @R19326
อาจารย์สันติสุขกำหนดที่ส่วนไหนครับว่าให้ Comma Delim หรือ Tab Delim
6 @R19328
คือผมทดลองสร้างไฟล์ที่ใช้ Tab ทีนึง ไม่ได้ผลก็เปลี่ยนไปใช้ Comma ทีนึง มันก็ใช้ได้ครับ ส่วนคำสั่งนี้ไม่มีที่กำหนดครับ เข้าใจว่ามันจะตรวจจับให้เอง
7 @R19329
ได้แล้วครับอาจารย์
ตามที่อาจารย์บอกต้องปรับ text file ให้เป็น comma delimit ก่อน
จากข้อมูลที่ผมมีเป็นค่าตัวเลขที่มี comma อยู่แล้วเลยต้องตัด comma ทิ้งก่อนแล้วค่อยเปลี่ยน tab เป็น comma ครับ
ส่วนผลการ import ตาม code ที่อาจารย์แนะนำมา ได้ตามที่ต้องการแล้วครับ
ขอบคุณมากครับ

On Error GoTo errr:
Dim sSearchText As String
Dim sReplaceText As String
Dim sFileName As String
Dim sFileText As String
Dim strText As String
Dim strNewText As String
Dim intWhere1 As Integer
Dim FirstPos
Dim objFSO As Object
Dim objFile As Object
Const ForReading = 1
Const ForWriting = 2
Dim i As Integer

'Change "," to "" from textfile.txt
sSearchText = ","
sReplaceText = ""
sFileName = "C:\Import\test2.txt"
'Create instance of FileSystemObject.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(sFileName, ForReading)
'read entire contents of file, save to strText variable
strText = objFile.ReadAll
objFile.Close
'Search for text in string.
strNewText = Replace(strText, sSearchText, sReplaceText, 1, 1, vbTextCompare)

FirstPos = 0
FirstPos = InStr(FirstPos + 1, strNewText, sSearchText, 1)

strNewText = Left(strNewText, FirstPos - 1) + Replace(strNewText, sSearchText, sReplaceText, FirstPos, -1, vbTextCompare)
Set objFile = objFSO.OpenTextFile(sFileName, ForWriting)
objFile.WriteLine strNewText
objFile.Close

'Change TAB to "," from textfile.txt
sSearchText = Chr(9)
sReplaceText = ","
sFileName = "C:\Import\test2.txt"
'Create instance of FileSystemObject.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(sFileName, ForReading)
'read entire contents of file, save to strText variable
strText = objFile.ReadAll
objFile.Close
'Search for text in string.
strNewText = Replace(strText, sSearchText, sReplaceText, 1, 1, vbTextCompare)

FirstPos = 0
FirstPos = InStr(FirstPos + 1, strNewText, sSearchText, 1)

strNewText = Left(strNewText, FirstPos - 1) + Replace(strNewText, sSearchText, sReplaceText, FirstPos, -1, vbTextCompare)
Set objFile = objFSO.OpenTextFile(sFileName, ForWriting)
objFile.WriteLine strNewText
objFile.Close

DoCmd.SetWarnings False
DoCmd.TransferText , , "ImportDetail", "C:\Import\test2.txt", -1
MsgBox "Finish!"
DoCmd.SetWarnings True

Exit Sub
errr:
MsgBox "Error # " & Err & " : " & Error(Err)
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.2695s