กระทู้เก่าบอร์ด อ.Yeadram
1,633 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 ข้อมูลลักษณะนี้มั้ยครับ
รบกวนด้วยครับ
ตอนนี้ผมมี 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
2 @R19315
เห็นบอกว่าแถวแรกเป็นชื่อ column แล้วตอน import ได้เลือกตัวเลือก First row contains field name หรือยังครับ นอกจากนี้ เราก็สามารถเลือกได้ว่าให้ใช้ Tab เป็น column/field delimiter ด้วยครับ
3 @R19319
เลือกครับอาจารย์
ปัญหาตอนนี้คือเป็นงานที่ต้องทำทุกวันครับถ้าให้ import แบบ manual คนใช้งานน่าจะงงครับ
ก่อนหน้านี้มีโปรแกรมที่คนเก่าเคยพัฒนาไว้ครับด้วย VB
ตัวโค้ดประมาณนี้ครับ (มีส่วนที่ประกาศ connection อีก แต่คร่าวๆคือประมาณนี้ครับ)
ตอนนี้กำลังลองแกะโค้ดมาใช้กับ 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
อาจารย์ท่านไหนเคยมีทำเคสแบบนี้ไว้รบกวนขอความรู้หน่อยครับ
ปัญหาตอนนี้คือเป็นงานที่ต้องทำทุกวันครับถ้าให้ 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 จะทำงานได้โดยไม่มีปัญหา ลองไปทดลองดูนะครับ
หมายเหตุ : ผมไม่แน่ใจว่าเครื่องผมมีปัญหาอะไรหรือเปล่า ผมทดลองโดยใช้ 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 ที่อาจารย์แนะนำมา ได้ตามที่ต้องการแล้วครับ
ขอบคุณมากครับ
ตามที่อาจารย์บอกต้องปรับ 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)
Time: 0.3383s
***การ import data text file ข้อมูลต้องมีโครงสร้างที่แน่นอน จึงจะทำการ import data แบบซ้ำๆได้ ถ้าเป็นกรณีต้องทำตามคำแนะนำขั้นต้น