Read text file in Access VBA - vba

I wrote some VBA code to write data from a text file.
In the file I have this text:
H|3434|0104-00000107844/18|Peter|Smith|
D|345345345|"III"|
| character is a delimiter for separating columns in the table.
Private Sub Polecenie8_Click()
Dim fieldname As String
fieldname = "d:\odebrane\tekst1.txt"
Dim strLineInput As String
Dim tekst As String
Dim strLineArray As Variant
Dim FileNum As Integer
FileNum = FreeFile()
Open fieldname For Input As #FileNum
Do While Not EOF(FileNum)
Line Input #FileNum, strLineInput
strLineArray = Split(strLineInput, "|")
tekst = strLineArray(3)
Loop
Me.Tekst0 = tekst
Close #FileNum
End Sub
strLineArray(0) is equal D not H and I don't know why.
I want to save this array in a table, so I want strLineArray(0) to be equal to H and strLineArray(5) to be equal to D.

How about something like this?
Sub imptxttable()
Dim DB As DAO.Database
Dim rst As DAO.Recordset
Dim fld As DAO.Field
Dim strSQL As String
Dim strfilepath As String
strfilepath = "your_file.txt"
strSQL = "Select * FROM " & strfilepath
Set DB = OpenDatabase("c:\test", False, False, "Text; Format=Delimited(|);HDR=Yes;CharacterSet=437")
Set rst = DB.OpenRecordset(strSQL)
Debug.Print rst.Fields(0).Name, rst.Fields(0)
With rst
.MoveLast
Debug.Print .RecordCount
.MoveFirst
For Each fld In rst.Fields
Debug.Print fld.Name
Next
End With
rst.Close
DB.Close
Set rst = Nothing
Set DB = Nothing
End Sub

Related

Vba ms-access Loop Recordset Print info to textbox

I made a sub that deletes records in a table via a recordset.
I would like to print the key of the record that is deleted to a textbox on a form.
So after each delete the key has to be added to the textbox on the form.
Below you can find the code, that doesn't print anything to the form.
I'm missing something.
Public Sub Erase()
Dim db As DAO.Database
Dim rs1 As DAO.Recordset
Dim strOutput As String
Dim i As Integer
Set db = CurrentDb()
Set rs1 = db.OpenRecordset("Table1", dbOpenDynaset) 'dynaset voor linked tables
If rs1.EOF Then Exit Sub
Do Until rs1.EOF
If rs1!Icoon = "del" Then
Debug.Print "Debug Print :" & rs1(0).Value
strOutput = "Ent: " & rs1(0).Value & vbCrLf
On Error Resume Next
rs1.Delete
txtOutput.value = strOutput
i = DoEvents
End If
rs1.MoveNext
Loop
rs1.Close
Set rs1 = Nothing
Set db = Nothing
End Sub
Forgot the form ... txtOutput.value = strOutput should be: [Forms]![Frm_Main]![txtOutput] = strOutput

ListBox Multiselect in MS Access

I have created a form to get all the field header names, but I'm unable to select multiple fields. Attached is for your reference.
Following is the code used to get the Headers from the Master Table:
Private Sub Form_Load()
'Call GetColumnNameFromIndex
'Call List4_Click
Dim rst As New ADODB.Recordset
rst.Open "SELECT * FROM Master_DataBase", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
' Note: adOpenForwardOnly and adLockReadOnly are the default values '
' for the CursorType and LockType arguments, so they are optional here '
' and are shown only for completeness '
Dim ii As Integer
Dim ss As String
For ii = 0 To rst.Fields.Count - 1
ss = ss & "," & rst.Fields(ii).Name
Next ii
Me.List4.RowSource = ss
Debug.Print ss
Me.Requery
End Sub
Set your properties to Simple or Extended.
Sample VBA code may look like this.
Option Compare Database
Private Sub cmdOpenQuery_Click()
On Error GoTo Err_cmdOpenQuery_Click
Dim MyDB As DAO.Database
Dim qdef As DAO.QueryDef
Dim i As Integer
Dim strSQL As String
Dim strWhere As String
Dim strIN As String
Dim flgSelectAll As Boolean
Dim varItem As Variant
Set MyDB = CurrentDb()
strSQL = "SELECT * FROM tblCompanies"
'Build the IN string by looping through the listbox
For i = 0 To lstCounties.ListCount - 1
If lstCounties.Selected(i) Then
If lstCounties.Column(0, i) = "All" Then
flgSelectAll = True
End If
strIN = strIN & "'" & lstCounties.Column(0, i) & "',"
End If
Next i
'Create the WHERE string, and strip off the last comma of the IN string
strWhere = " WHERE [strCompanyCountries] in (" & Left(strIN, Len(strIN) - 1) & ")"
'If "All" was selected in the listbox, don't add the WHERE condition
If Not flgSelectAll Then
strSQL = strSQL & strWhere
End If
MyDB.QueryDefs.Delete "qryCompanyCounties"
Set qdef = MyDB.CreateQueryDef("qryCompanyCounties", strSQL)
'Open the query, built using the IN clause to set the criteria
DoCmd.OpenQuery "qryCompanyCounties", acViewNormal
'Clear listbox selection after running query
For Each varItem In Me.lstCounties.ItemsSelected
Me.lstCounties.Selected(varItem) = False
Next varItem
Exit_cmdOpenQuery_Click:
Exit Sub
Err_cmdOpenQuery_Click:
If Err.Number = 5 Then
MsgBox "You must make a selection(s) from the list", , "Selection Required !"
Resume Exit_cmdOpenQuery_Click
Else
'Write out the error and exit the sub
MsgBox Err.Description
Resume Exit_cmdOpenQuery_Click
End If
End Sub
Please customize to your specific needs.

Trying to copy Description property from DB to external DB (error 3270)

I have created and manipulated an external database from the existing tables in my current database.
The matter is that I necessarily have to manipulate "Description" property in the new database fields.
When I try to retrieve "Description" property from cereated external database, response is that "Description" isn't a property (Error 3270, "property not found")
How could I do it?
I tried the following code:
Sub Actualizacomentarios()
Dim dbFinal As DAO.Database
Dim tbl As DAO.TableDef
Dim fld As DAO.Field
Dim tblFinal As DAO.TableDef
Dim fldFinal As DAO.Field
Dim prpFinal As DAO.Property
Set dbFinal = DBEngine.OpenDatabase("D:\Dropbox\Expedientes JLE nueva epoca activos\17002 - Fermin Torres. Programa\NuevoFoasat.accdb")
For Each tbl In CurrentDb.TableDefs
If InStr(tbl.Name, "JLE_") > 0 Then
For Each fld In tbl.Fields
Set tblFinal = dbFinal.TableDefs(tbl.Name)
Set fldFinal = tblFinal.Fields(fld.Name)
fldFinal.Properties("Description") = fld.Properties("Description") 'HERE OCCURS ERROR
Next fld
End If
Next tbl
dbFinal.Close
Set dbFinal = Nothing
Rewritten and working . Thanks to #HansUp
Sub Actualizacomentarios()
Dim dbFinal As DAO.Database
Dim tbl As DAO.TableDef
Dim fld As DAO.Field
Dim tblFinal As DAO.TableDef
Dim fldFinal As DAO.Field
Dim prpFinal As DAO.Property
Set dbFinal = DBEngine.OpenDatabase("D:\Dropbox\Expedientes JLE nueva epoca activos\17002 - Fermin Torres. Programa\NuevoFoasat.accdb")
For Each tbl In CurrentDb.TableDefs
If InStr(tbl.Name, "JLE_") > 0 Then
For Each fld In tbl.Fields
Set tblFinal = dbFinal.TableDefs(tbl.Name)
Set fldFinal = tblFinal.Fields(fld.Name)
On Error GoTo ErrorTrap
If Nz(fld.Properties("Description"), "") <> "" Then
Set prpFinal = fldFinal.CreateProperty("Description")
prpFinal.Type = dbText
prpFinal.Value = fld.Properties("Description")
fldFinal.Properties.Append prpFinal
'Debug.Print fldFinal.Name, fldFinal.Properties("Description")
fldFinal.Properties("Description") = fld.Properties("Description")
End If
On Error GoTo 0
Next fld
End If
Next tbl
dbFinal.Close
Set dbFinal = Nothing
Exit Sub
ErrorTrap:
If Err.Number = 3367 Then
Debug.Print "Property already exists on " & tbl.Name & " (Field: " & fld.Name & ")"
Else
Stop
Debug.Print "Not Found or empty on " & tbl.Name & " (Field: " & fld.Name & ")"
End If
Resume Next
End Sub

Read only one record from Multiple text files into Excel using VBA

I have multiple txt files in a folder, which are tab delimited. Each of these files have a column called EngagementId, which is the same value, irrespective of number of records. However, it changes for every txt file, which is what I want to capture.
I am trying to get the file name in the first row. The GetFileNames() works for that (as pointed out in the comments)
Sub GetFileNames()
Dim sPath As String
Dim sFile As String
Dim iRow As Integer
Dim iCol As Integer
Dim splitFile As Variant
'specify directory to use - must end in "\"
sPath = ActiveWorkbook.Path
iRow = 0
sFile = Dir(sPath & "\Individual Reports\")
Do While sFile <> ""
iRow = iRow + 1
splitFile = Split(sFile, ".txt")
For iCol = 0 To UBound(splitFile)
Sheet1.Cells(iRow, iCol + 1) = splitFile(iCol)
Next iCol
sFile = Dir ' Get next filename
Loop
End Sub
Each of these txt files have one column (which is in the 13th position in each of the text files), called "EngagementId". I want to pull only the first "Engagement Id", which is from the 2nd row(since the first row contains headers).
Sub Extractrec()
Dim filename As String, nextrow As Long, MyFolder As String
Dim MyFile As String, text As String, textline As String
MyFolder = ActiveWorkbook.Path
MyFile = Dir(MyFolder & "\Individual Reports\*.txt")
Do While MyFile <> ""
Open (MyFolder & MyFile) For Input As #1
Do Until EOF(1)
Line Input #1, LineFromFile
LineItems = Split(LineFromFile, "\t") 'second loop text is already stored
'-> see reset text
Sheet1.Cells(iRow, iCol + 2).Value = LineItems(13, 2)
Loop
Close #1
Loop
Using an ADODB.Recordset to query would be more versatile.
Sub Example()
On Error Resume Next
Dim rs As Object, f As Object, conn As Object
Dim FolderPath As String, FileName As String, FilterString As String
FolderPath = "C:\Users\best buy\Downloads\stackoverfow\Sample Data File\"
FileName = "example.csv"
FilterString = "WHERE EngagementId = 20"
Set rs = getDataset(FolderPath, FileName, FilterString)
Do While Not rs.BOF And Not rs.EOF
Debug.Print rs.Fields("EngagementId")
Debug.Print rs.Fields("Company")
Debug.Print rs.Fields("City")
Debug.Print rs.Fields("State")
rs.MoveNext
Loop
Set conn = rs.ActiveConnection
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
End Sub
Function getDataset(FolderPath As String, FileName As String, FilterString As String) As Object
Dim conn As Object, rs As Object
Set conn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
conn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FolderPath & ";" & _
"Extended Properties=""text; HDR=Yes; FMT=Delimited; IMEX=1;""")
rs.ActiveConnection = conn
rs.Source = "SELECT * FROM " & FileName & " " & FilterString
rs.Open
Set getDataset = rs
End Function
Since you only need the second line of each file, you don't need to loop, just read and discard the fist line, then read and split the second one:
Open (MyFolder & MyFile) For Input As #1 'MyFolder & MyFile won't be the correct name (probably should be MyFolder & "\Individual Reports\" & MyFile)
Line Input #1, LineFromFile 'line to discard
Line Input #1, LineFromFile 'line to use
LineItems = Split(LineFromFile, vbTab)
Sheet1.Cells(someplace).Value = LineItems(13) ' replace some place with the correct value that we don't know
Close #1

Create Access table from text file

I need to create an access (2007) table from a text file. I know ahead of time what columns should exist, but from time to time the vendors slip up and submit a text file that contains an incorrect number of columns. So I don't want to specify the columns in advance. I want to load all data as text into whatever columns exist. Then I will do QC.
The columns are pipe delimited and there are over 200 columns per record. There are no column headers, but there is one line of header text for the file, and one line at the end that states how many records there are. There may be anywhere from 1 to over 5,000 records in a text file. Records are identified with CRLF (windows).
Here is what I have so far, and it works (in that it reads the file and places the correct information in the recordset (columns and records), and I can count the number of records), except that the SELECT INTO gives me an error:
Sub OpenTextADO(strFileName As String, strPath As String)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field
Dim recs As Integer
Dim strRecord As String
Dim strSQL As String
recs = 0
Set cn = New ADODB.Connection
If Right(strFileName, 3) = "txt" Then
'cn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)};" & "DBQ=" & strPath & "\" 'need schema.ini file
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strPath & "\;Extended Properties='text;HDR=No;FMT=Delimited(|)'" 'need schema.ini file
End If
Set rs = New ADODB.Recordset
rs.Open "SELECT * INTO TESTTEXT FROM [" & strFileName & "]", cn, adOpenStatic, adLockOptimistic, adCmdText
'Do Until rs.EOF
' For Each fld In rs.Fields
' strRecord = strRecord & "|" & fld.Value
' Next fld
' strRecord = strRecord & vbCr
' recs = recs + 1
' rs.MoveNext
'Loop
'Debug.Print strRecord
'recs = rs.RecordCount
rs.Close
Set rs = Nothing
MsgBox "Text was opened and there are " & recs & " records in the table."
cn.Close
Set cn = Nothing
End Sub
NOTE: I included both the OLEDB version and the text driver version - they both seem to operate identically. I also created a schema.ini file that looks like this:
[test.txt]
Format=Delimited(|)
ColNameHeader=False
Both drivers seem to need this to desregard column headers, despite the "HDR=No" in the OLEDB version.
The error I get is: "Cannot update. Database or object is read-only".
I appreciate any help.
Could you do a sequential read of the text file, using the count of pipe-delimited fields in the first data line of the file to create a table with the proper number of columns, then just write subsequent lines into that table? I just threw the following together, but it seems to work.
Public Function import_txt_to_db(strFile As String) As Boolean
On Error GoTo ErrHandle
Dim strLine As String
Dim intFileNum As Integer
Dim blnFirstLine As Boolean
blnFirstLine = True
Dim varArray As Variant
intFileNum = FreeFile
Open strFile For Input Access Read As intFileNum
Do While Not EOF(intFileNum)
Line Input #intFileNum, strLine
varArray = Split(strLine, "|")
If blnFirstLine = True Then
'Use count of fields in first line to determine # of columns to create
Dim intColCount As Integer
intColCount = UBound(varArray)
Dim strQry As String
strQry = "CREATE TABLE tblImport ("
Dim intCtr As Integer
For intCtr = 1 To intColCount + 1
strQry = strQry & "[COLUMN_" & intCtr & "] TEXT(255),"
Next intCtr
strQry = Left(strQry, Len(strQry) - 1) & ")" 'get rid of terminal comma
CurrentDb.Execute strQry
blnFirstLine = False
End If
Dim strQry2 As String
strQry2 = "INSERT INTO tblImport VALUES('" & Replace(strLine, "|", "','") & "')"
CurrentDb.Execute strQry2
Loop
Close #intFileNum
import_txt_to_db = True
Exit Function
ErrHandle:
import_txt_to_db = False
End Function
I did a simple test with the folowing five-line text file
Thomas|Jefferson|Virginia
Bill|Clinton|Arkansas
Jimmy|Carter|Georgia
Lyndon|Johnson|Texas
George|Washington|Virginia
After running the code, here's my (simple) table: