Attaching additional lines on top of a Access CSV export - vba

I have a process in MS Access where I am exporting the result of a query into a csv format using the DoCmd TransferText method, and using an export specification to contain the field names.
However, I need to attach to the beginning of this file several lines- all of a fixed value- I'm naming this in my code with vbCrLf to separate the several lines I need. How can I append this to the top of the file after it is created. So my file needs to look like this, with the three extra lines for example at the top, with the csv export contents directly below. How can I achieve this? Thanks!
***(need this line 1)
(need this line 2)
(need this line 3)***
field1,field2,field3
x, y, z

As #TimWilliams has suggested, you will need to use VBA to do this. Below is some code that exports the query to a text file using .TransferText, then opens it and imports the data as one chunk, before writing back out the three header lines and the original data:
Sub sExportCSV()
On Error GoTo E_Handle
Dim strFile As String
Dim strLine1 As String
Dim strLine2 As String
Dim strLine3 As String
Dim strData As String
Dim intFile As Integer
strLine1 = "This is line 1"
strLine2 = "This is the second line"
strLine3 = "And this is the last line"
strFile = "J:\test-data\csv.txt"
DoCmd.TransferText acExportDelim, , "qdfExport", strFile, False
intFile = FreeFile
Open strFile For Input As intFile
strData = Input(LOF(intFile), intFile)
Close #intFile
intFile = FreeFile
Open strFile For Output As intFile
Print #intFile, strLine1 & vbCrLf & strLine2 & vbCrLf & strLine3 & vbCrLf & strData
Close #intFile
sExit:
On Error Resume Next
Close #intFile
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sExportCSV", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Regards,

Related

Replace a string in a .csv file before import into MS Access

I need to import multiple csv files into one access table, but before the import i would like to replace ",," with ",". Is there any way to do this?
For now i've got this code that only imports the files:
Private Sub bImportFiles_Click()
On Error GoTo bImportFiles_Click_Err
Dim objFS As Object, objFolder As Object
Dim objFiles As Object, objF1 As Object
Dim strFolderPath As String
Dim ts, tse As Date
ts = Now() 'Initializare start import
'Import fisiere colectare
strFolderPath = "C:\Users\costicla\test\"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFS.GetFolder(strFolderPath)
Set objFiles = objFolder.files
For Each objF1 In objFiles
If Right(objF1.Name, 3) = "csv" Then
DoCmd.SetWarnings False
DoCmd.TransferText acImportDelim, "specs", "ALL", strFolderPath & objF1.Name, False
'DoCmd.RunSQL "INSERT INTO COLL_ALL ( Data_Inc, CNP, CB, CN, COM, N_UNITS, PUAN, Price, SN_ACT )"
Name strFolderPath & objF1.Name As "C:\Users\costicla\import\" & objF1.Name 'Move the files to the archive folder
End If
Next
Set objF1 = Nothing
Set objFiles = Nothing
Set objFolder = Nothing
Set objFS = Nothing
'tse = Now()
DoCmd.SetWarnings True
'MsgBox ("Import done !!! start at:" & ts & " end at:" & tse)
MsgBox ("Import ALL done !!! " & _
"start at: " & ts & " end at: " & tse)
bImportFiles_Click_Exit:
Exit Sub
DoCmd.SetWarnings True
bImportFiles_Click_Err:
MsgBox Err.Number & " " & Err.Description
Resume bImportFiles_Click_Exit
End Sub
You can use VBA's File I/O operations to open a file, import all of the data in one go, replace the double commas and output it to a new file. The code below should get you started:
Sub sReplaceDoubleComma(strInFile As String)
On Error GoTo E_Handle
Dim intInFile As Integer
Dim strOutFile As String
Dim intOutFile As Integer
Dim strInput As String
intInFile = FreeFile
Open strInFile For Input As intInFile
strOutFile = "J:\test-data\temp.txt"
intOutFile = FreeFile
Open strOutFile For Output As intOutFile
strInput = Input(LOF(intInFile), intInFile)
Print #intOutFile, Replace(strInput, ",,", ",")
Close #intInFile
Close #intOutFile
' Kill strInFile
' Name strOutFile As strInFile
sExit:
On Error Resume Next
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sReplaceDoubleComma", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Once you are happy that this works, you can uncomment the two lines towards the end to replace the input file.
You can then call this procedure from within part of your existing code:
For Each objF1 In objFiles
If Right(objF1.Name, 3) = "csv" Then
DoCmd.SetWarnings False
Call sReplaceDoubleComma(strFolderPath & objF1.Name)
DoCmd.TransferText acImportDelim, "specs", "ALL", strFolderPath & objF1.Name, False
Name strFolderPath & objF1.Name As "C:\Users\costicla\import\" & objF1.Name 'Move the files to the archive folder
End If
Next
Link, don't import, the file, and you have a linked table.
Now, use this linked table as source in a simpel select query where you filter, modify, and convert the data and alias the fields as needed.
Then use this query as source in an append query that will add the records to your COLL_ALL table.

MS Access VBA Open a Text file and write to a specific line without overwriting the file

I have a text file that I would like to add a header and a footer to. I don't want to overwrite the first or last lines, rather I'd like to add a new first line and append a line to the end of the file.
The below Function works for appending to the bottom of the file but I'd like to be able to control where the line is inserted. Thank you!
Function WriteToText(sFile As String, sText As String)
On Error GoTo Err_Handler
Dim iFileNumber As Integer
iFileNumber = FreeFile ' Get unused file number
Open sFile For Append As #iFileNumber ' Connect to the file
Print #iFileNumber, sText ' Append our string
Close #iFileNumber ' Close the file Exit_Err_Handler:
Exit Function Err_Handler:
MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: Txt_Append" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occured!"
GoTo Exit_Err_Handler End Function
What you do for a task like this:
Read the whole file into a string (Open For Input)
Add the data you want: S = "header line" & vbCrLf & S & vbCrLf & "footer line"
Write the whole string to the file, overwriting it (Open For Output)

VBA Access 2010 DIR results in empty string

I have the following code:
Private Sub cmdExportTERNAME_Click()
On Error Resume Next
Me.MsgFld = "Please wait... exporting TERNAME file."
Dim expLoc As String
Dim xFile As String, myFile As String
Dim myFlag As Integer
expLoc = "I:\Investigative Names\" ' PRD
xFile = Dir(expLoc & "NAME - ForUpload.txt", vbDirectory)
myFile = "NAME-ForUpload.txt"
myFlag = StrComp(xFile, myFile)
If myFlag <> -1 Then
Kill expLoc & "NAME-ForUpload.txt"
End If
' Export text files for upload
DoCmd.TransferText acExportFixed, "SpecTERNAME", "qry_TERNAME", expLoc & "NAME-ForUpload.txt"
xFile = Dir(expLoc & "TNAME-ForUpload.txt")
myFile = "NAME-ForUpload.txt"
myFlag = StrComp(xFile, myFile)
If myFlag <> -1 Then
GoTo ContinueProcessing1
Else
MsgBox "The program was not able to export the NAME file for upload." & Chr(13) & Chr(13) & "Please notify IS Department.", vbCritical, "ERROR MESSAGE BOX"
GoTo exitRTN
End If
ContinueProcessing1:
exitRTN:
End Sub
So I have 2 more of these subroutines with different text files which work fine but this block of code doesn't find xFile, it return a empty string which causes the program to display the message box error. I can't figure out why the same code with different text file works before it reaches this code. The weird thing is it sometimes finds the correct xFile name in debug mode but not when run normally. Can someone help me figure this out?
Thanks

VBA procedure to import only selected csv files (from one folder) into a single table in access

I have a folder that contains 2000 *.csv files. But not all of them are important 4 me. Only 60 of them are important, and I have them listed, by names in access table. there is no header - only file names that need to be read into the single table database.
it looks like this:
these *.mst files are really *.csv files - it will work that way.
I need a VBA procedure, that imports ONLY SELECTED files (these listed in the table) out of this folder into a single access table.
yes, all these files have exactly the same structure, so they can be merged into these access table and that is the goal of this VBA procedure.
this is how every file looks like:
the code I already got just pulls every file from this folder and imports it into the single table in access.
I need it changed to pull only the selected files.
destination table name is: "all_stocks"
Sub Importing_data_into_a_single_table()
Dim start As Double
Dim total_time As String
Dim my_path As String, my_ext As String, my_file As String
Dim FileNum As Integer
Dim DataLine As String
Dim pola() as String
Dim SQL1 As String, file_array() As String
start = Timer
my_path = "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\" 'Source folder.
my_ext = "*.mst" ' all files with .mst extension.
my_file = Dir(my_path & my_ext) ' take the first file from my_path.
DoCmd.SetWarnings False ' turn off warnings.
Do While my_file <> ""
FileNum = FreeFile()
Open my_path & my_file For Input As #FileNum
Line Input #FileNum, DataLine
' Reads a single line from an open sequential file and assigns it to a String variable.
While Not EOF(FileNum) ' EOF function returns a Boolean value True when the end of a file.
Line Input #FileNum, DataLine
pola = Split(DataLine, ",")
SQL1 = "INSERT INTO Tabela1 (Ticker, day, open, high, low, close, vol) VALUES('" & pola(0) & "', " & _
pola(1) & ", " & pola(2) & ", " & pola(3) & ", " & _
pola(4) & ", " & pola(5) & ", " & pola(6) & ")"
Debug.Print SQL1
DoCmd.RunSQL SQL1
Wend
Close
my_file = Dir()
Loop
DoCmd.SetWarnings True
total_time = Format((Timer - start) / 86400, "hh:mm:ss")
' total_time = Round(Timer - start, 3)
MsgBox "This code ran successfully in " & total_time & " minutes", vbInformation
End Sub
If You could optimize this code to run faster, please be my guest.
Now its importing the data using "Line Input" method, and I've heard, that there are some better ways to do that, but I'm no programmer myself so I'm dependent on Your help my friends.
Thank U for all help and code provided :-)
screen shot 4 for A.S.H
Listing the 2000+ files in the directory, checking if each is listed in the selection table, is not the right approach. It is surely preferable to read the selected files from the table and access them one by one.
The other potential speedup is using the built-in DoCmd.TransferText (as already pointed in other answers). Built-ins are usually very optimized and robust so you should prefer them unless there's a specific reason. Your own tests should confirm it.
Sub Importing_data_into_a_single_table()
Dim my_path As String, rs As Recordset, start As Double, total_time As String
my_path = "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\" 'Source folder.
DoCmd.SetWarnings False
start = Timer
Set rs = CurrentDb.OpenRecordset("Selected_Files")
Do Until rs.EOF
If Dir(my_path & rs.Fields(0).Value) <> "" Then
DoCmd.TransferText , , "Tabela1", my_path & rs.Fields(0).Value, True
' You could also use your code's loop here; Open my_path & my_file For Input As #FileNum etc..
End If
rs.MoveNext
Loop
DoCmd.SetWarnings True
total_time = Format(Timer - start, "hh:mm:ss")
MsgBox "This code ran successfully in " & total_time, vbInformation
End Sub
I would try using a combination of different method. I will admit I have never interacted with a .mst file in the manner youre using them but I think what IM suggesting will still work perfectly fine.
Use this to check table for file name:
Do While my_file <> "" 'some where after this line
If Isnull(Dlookup("your field name", "your table name", "Field name='" & my_file & "'") = False then
'do stuff b/c you found a match
else
'dont do stuff b/c no match
end if
Then you could use DoCmd.TransferText to import the entire file into the table
Documentation of transfer text method
https://msdn.microsoft.com/VBA/Access-VBA/articles/docmd-transfertext-method-access
I use frequently Excel vba. This bellows is Excel vba method. Compare the speed of this with your method.
Sub OpenCSvs()
Dim sWs As String, Fn As String
Dim Wb As Workbook
Dim start As Double
Dim total_time As String
Dim my_path As String, my_ext As String, my_file As String
start = Timer
my_path = "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\" 'Source folder.
my_ext = "*.mst" ' all files with .mst extension.
my_file = Dir(my_path & my_ext) ' take the first file from my_path.
Do While my_file <> ""
Fn = my_path & my_file
Set Wb = Workbooks.Open(Fn, Format:=2)
sWs = ActiveSheet.Name
With ActiveSheet
.Rows(1).Insert
.Range("a1").Resize(1, 7) = Array("Ticker", "day", "open", "high", "low", "close", "vol")
End With
ExportToAccess Fn, sWs
Wb.Close (0)
my_file = Dir()
Loop
total_time = Format((Timer - start) / 86400, "hh:mm:ss")
MsgBox "This code ran successfully in " & total_time & " minutes", vbInformation
End Sub
Sub ExportToAccess(myFn As String, sWs As String)
Dim PathOfAccess As String
Dim strConn As String, strSQL As String
PathOfAccess = "C:\Database6.accdb" '<~~ your database path
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & PathOfAccess & ";"
Set cn = CreateObject("ADODB.Connection")
cn.Open strConn
strSQL = "INSERT INTO Tabela1 (Ticker, day, open, high, low, close, vol) select * from [" & sWs & "$] IN '' " _
& "[Excel 8.0;HDR=yes;IMEX=2;DATABASE=" & myFn & "]"
cn.Execute strSQL
End Sub

Using textstream object to replace tab with spaces and delete characters

I have over a thousand .s2p files (a delimited text file used by electrical testing equipment) that were edited by a VBA macro, which opened each raw file in Excel as a tab-and-space delimited text file, and replaced a few of the columns with data columns from another file, then saved them in original format (.s2p) and closed them. This is the call I used to open the each file:
Call Application.Workbooks.OpenText(Filename:=(path & filename & ".s2p"), Origin:="437", DataType:=xlDelimited, ConsecutiveDelimiter:=True, Tab:=True, Space:=True, TextQualifier:=xlTextQualifierNone)
Now, when I open the .s2p files in Notepad to view them, the original single space separating the columns is now a full tab, and some double quote (") characters were added to some of the file header lines (despite setting TextQualifier parameter to xlTextQualifierNone...)
Because of this I want to write another macro that can open all of these .s2p files again, loop through the lines, and replace any double quotes with blanks, and any tabs with single spaces. I was planning to use .OpenAsTextStream on each file, but it seems like the TextStream object doesn't support overwriting lines, but can only write new lines...
Is there a better way to achieve what I am trying to do than just reading lines from the original file, and writing them to a newly created file? It is imperative that I save the final file as ".s2p" and not ".txt".
You don't need the text streams, just the basic input output actions available in VBA.
Option Explicit
Sub test()
FixFile "c:\temp\mytestfile.s2p"
End Sub
Sub FixFile(filename As String)
Dim fnum As Integer
Dim fileText As String
Dim finalText As String
fnum = FreeFile
On Error Resume Next
Open filename For Input As #fnum
If Err.Number <> 0 Then
Debug.Print "Critical error attempting to open " & filename & _
". Error #" & Err.Number & ": " & Err.Description
Exit Sub
End If
finalText = ""
Do Until EOF(fnum)
Line Input #fnum, fileText
fileText = Replace(fileText, """", " ", , , vbTextCompare)
fileText = Replace(fileText, vbTab, " ", , , vbTextCompare)
finalText = finalText & fileText & vbCrLf
Loop
Close fnum
fnum = FreeFile
Open filename For Output As #fnum
Print #fnum, finalText
Close fnum
End Sub
Edited to show line by line read with a final write.