Save a query as text tab delimited but include ".ail2" in the saved name. (ACCESS) - ms-access

I want to export a query as a text file from an access database but using vba. The issue is I need to save it with .ail2 in the name.
basically I want it of the form: "currentdate_version.ail2".txt (the quotations are very important otherwise it won't work).
So for example todays first version would look like:
"20182910_1.ail2".txt
I have tried exporting it manually and saving it as this but the export wizard doesn't seem to like the quotation marks in the saved name. I have therefore been exporting it (using a custom saved export that i've labelled test1 - it includes the headers of each column, sets the text qualifier as 'none', the field delimiter as 'tab' and file format is 'delimited').
I am using the following code in access, the first part just makes sure the folder with the current date exists.
Private Sub ExportExcel()
Dim myQueryName As String
Dim myExportFileName As String
Dim strSheets As String
Dim sFolderPath As String
Dim filename As Variant
Dim i As Integer
strSheets = Format(Date, "yyyymmdd")
sFolderPath = "M:\AIL2Files\" & strSheets & ""
Dim fdObj As Object
Set fdObj = CreateObject("Scripting.FileSystemObject")
If fdObj.FolderExists("" & sFolderPath & "") Then
Else
fdObj.CreateFolder ("" & sFolderPath & "")
End If
i = 1
filename = Dir(sFolderPath & "\*" & i & ".txt")
Do While Len(filename) > 0
filename = Dir(sFolderPath & "\*" & i & ".txt")
i = i + 1
Loop
myQueryName = "001_querytest"
myExportFileName = "" & sFolderPath & "\" & Chr(34) & "" & strSheets & "_" & i & ".ail2" & Chr(34) & ".txt"
DoCmd.TransferText acExportDelim, "test1", myQueryName, myExportFileName, True
End Sub
test1 isn't being picked up even though its a 'saved export'. I assume I'm doing this part wrong... but even still I reckon the save won't be successful and will not include the quotation marks.
Thanks.
EDIT:
I have tried doing the following instead:
DoCmd.TransferText transferType:=acExportDelim, TableName:=myQueryName, filename:=myExportFileName, hasfieldnames:=True
It now saves, but again not including the quotation marks as desired. Whats interesting is when I type ?myExportFileName in the immediate window, it displays my desired filename but the command is clearly not working correctly as I get it of the form:
_20181029_1#ail2_
Instead...
Here is image if I use save as:
I end up getting:

There are some misconceptions here.
Windows file names cannot contain double quotes ", period. And you don't need them, either. Just save your file as filename.ail2.
This is what you get when doing "Save as". Tell Explorer to show file extensions, and you'll see that you don't have "filename.ail2".txt but filename.ail2.
You only need
myExportFileName = sFolderPath & "\" & strSheets & "_" & i & ".ail2"
test1 isn't being picked up even though its a 'saved export'.
DoCmd.TransferText doesn't use saved exports, but export specifications. See here for the difference:
Can I programmatically get at all Import/Export Specs in MS Access 2010?
Addendum
DoCmd.TransferText could throw a runtime error when given an illegal file name, but apparently it tries to save the day by exchanging the illegal characters by _, hence _20181029_1#ail2_ (.txt)

A workaround to this is first saving the file as a .txt using DoCmd.TransferText, but running a shell and renaming. Like such:
myExportFileName = sFolderPath & "\" & strSheets & "_" & i & ".txt"
DoCmd.TransferText TransferType:=acExportDelim, SpecificationName:="034_AILFILE Export Specification", TableName:=myQueryName, filename:=myExportFileName, HasFieldnames:=True
Set wshShell = CreateObject("Wscript.Shell")
strDocuments = wshShell.SpecialFolders("M:\AIL2Files\" & strSheets & "")
oldFileName = myExportFileName
newFileName = sFolderPath & "\" & strSheets & "_" & i & ".ail2"
Name oldFileName As newFileName
There is undoubtedly cleaner ways of doing this but I imagine that this method could be used to save any files that have non traditional extensions, but fundamentally follow the format of a .txt file.

Related

vba WScript.Shell to run exe with JSON string as argument

I'm attempting to run an exe via command line that requires a JSON string as an argument. Inside that JSON string are dynamic start/end date variables, and a file name variable.
I'm able to run the command with the Shell function, however I need the waitTillComplete functionality of WScript.Shell.
This is how the string looks when I pass it to Call Shell() {which runs successfully}
C:\Users\API\Client.exe /api/v2/ro/my/deposits {\"startDateInOut\":\"2022-09-30\",\"enddate\":\"2022-10-08\"} deposit-2022-09-30_2022-10-08.JSON
After much searching I still cannot for the life of me figure out how to structure this so shell.Run() will accept it.
Here is what I've got so far:
Sub test()
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorcode As Integer
Dim path As String
startDateInOut = "2022-10-01"
EndDate = "2022-10-10"
client = "C:\Users\API\Client.exe"
arg_1 = "/api/v2/ro/my/deposits {\""startdate\"":\" & """" & startDateInOut & "\""" & ",\""enddate\"":\" & """" & EndDate & "\""}" & " " & "test.json"
path = Chr(34) & client & Chr(34) & " " & Chr(34) & arg_1 & Chr(34)
Debug.Print path
goClient = shell.Run(path, style, waitTillComplete)
End Sub
If possible I would like to avoid using a batch file and keep everything inside of the vba module.
Any help would be greatly appreciated!

Pointing MS Access to a variable path in VBA for exporting to Excel

I have a project I work on frequently, the data comes in Access & I need to export to Excel. The following code always worked until my company upgraded to Windows 2010 a couple of years ago. What happens is I'll point to the subdir I want (e.g. P:\project\evaluation\output) and it will save one subdir up (e.g. P:\project\evaluation).
The code:
Sub ExporttoXL()
Dim response, today
exportdir = fncOpenFolder()
today = Format(Date, "mmddyy")
response = InputBox("What is the date for the title of the output file? (Recommend: mmddyy format)", "Output file date for name", today)
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, _
"Query001", "Output-" & response & ".xls"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, _
"Query002", "Output-" & response & ".xls"
End Sub
----------------
Public Function fncOpenFolder() As String
Dim fdlg As Object
Set fdlg = Application.FileDialog(4) 'msoFileDialogFolderPicker
With fdlg
.AllowMultiSelect = False
.Title = "Select Folder"
If .Show = -1 Then
fncOpenFolder = .SelectedItems(1)
Else
fncOpenFolder = ""
End If
End With
Set fdlg = Nothing
End Function
The FileName argument to TransferSpreadsheet is supposed to be "the file name and path of the spreadsheet you want to import from, export to, or link to." But your code is giving it only the file name without the path. The exportdir variable is not used after you give it a value from fncOpenFolder().
Revise the code and use exportdir to include the path with the file name for the workbook which you want as the export target ...
Dim strFullPath As String
strFullPath = exportdir & "\Output-" & response & ".xls"
Debug.Print strFullPath '<- view this in Immediate window; Ctrl+g will take you there
'DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, _
' "Query001", "Output-" & response & ".xls"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, _
"Query001", strFullPath

How to select the file whose name includes the newest date?

I am importing a CSV file into a table in MS Access.
However there are many files in the folder with the same extension and the names include dates in "mm_dd_yyyy" format.
Example: Lets say I have two CSV files:
my_music_02_10_2013_01_58_07_PM.csv
my_music_02_11_2013_03_04_07_PM.csv
Both files are in the same folder, myfolder. I want to import the file whose name contains the newest date.
Here is a short snippet of my code:
strPath = "F:\myfolder\"
strFile = Dir(strPath & "my_music" & "*.csv")
How can I determine which of my "my_music*.csv" is newest?
Seems to me the key is to extract the Date/Time from each file name so that you may compare those to find which of them is newest.
Here is an Immediate window session testing the function included below. The function returns null if it can't find a string which represents a valid date.
? DateFromFilename("my_music_02_10_2013_01_58_07_PM.csv")
2/10/2013 1:58:07 PM
? DateFromFilename("my_music_no_date_here.csv")
Null
Public Function DateFromFilename(ByVal pFileName As String) As Variant
Dim strBaseName As String
Dim strDate As String
Dim strPieces() As String
Dim varReturn As Variant
varReturn = Null
strBaseName = Split(pFileName, ".")(0)
'Debug.Print "strBaseName: " & strBaseName
strPieces = Split(strBaseName, "_")
If UBound(strPieces) = 8 Then
strDate = strPieces(4) & "-" & strPieces(2) & _
"-" & strPieces(3) & " " & strPieces(5) & ":" & _
strPieces(6) & ":" & strPieces(7) & " " & strPieces(8)
End If
'Debug.Print "strDate: " & strDate
If IsDate(strDate) Then
varReturn = CDate(strDate)
End If
DateFromFilename = varReturn
End Function

MS Access VBA FileSystemObject does not accept path with spaces in them

How do I get around the limitation VBA have of not allowing spaces in file path when using the FileSystemObject?
Here is my code:
from= "C:\Users\MyAccount\Desktop\a.txt"
to= "C:\Users\MyAccount\Desktop\Folder Name With Spaces\b.txt"
Dim fso As New FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CopyFile from, to
I have already tried the trick with adding " before any spaces, it doesn't work. The "Bad FileName or Number" error actually pops up.
I have also tried to replace any spaces with %20, which also does not work.
To clarify, I don't know the path beforehand, it is entered by the user.
There's no restriction around having spaces in filenames or paths, either in VBA or when using the FSO. You must have some other problem.
For example I don't think FSO will create a destination folder if it doesn't already exist.
Also: you don't need to use Createobject if you Dim ... As New ...: your object is created in the Dim statement.
My solution to the same issue:
Dim folderPath As String
folderPath = "D:\MyData\BackUp\capdat\City Name"
If Len(Dir$((folderPath & "\OLDData" & Format(Date, "-ddmmyyyy") & ".accdb"))) > 0 Then
Kill (folderPath & "\OLDData" & Format(Date, "-ddmmyyyy") & ".accdb"
Else
Do something
End if
its a while since I did any VBA but I think you need to enclose your strings in quotes to negate the spaces in the paths, so does this work:
fso.CopyFile """" + from + """", """" + to+ """"
EDIT:
This site suggested this routine:
Private Function GetQuotedArgument(ByVal argument As String) As String
Const Quote As String = """"
Return String.Format("{0}{1}{0}", Quote, argument)
End Function
giving:
fso.CopyFile GetQuotedArgument(from), GetQuotedArgument(to)
Failing that you'll have to resort to short forms of the file names... Microsoft article on doing that here, not sure if it applies to VBA though

Text-search in properties Access objects

Is there a way in Access to search for a certain text in object properties and so on? Just not only in the VBA source code.
I'm asking this because if I change for example the name of a field in a table I've to check a lot of object properties (Record Source, Control Source, Order By, ...). This can be done by trail-and-error or by checking all properties of each control of the forms, but that takes a lot of time.
One option is the Find and Replace tool (nice tool!), but it's a bit of overkill for me. I don't need a text replace (only 'find') and it's 37 dollar for a tool I'll only use a few times a year.
Other suggestions?
There is something I often use to find out where some function or query may be hidding somewhere unexpected (in a bound control's RowSource of within a sub-query for instance).
I use an undocumented feature to export all Access objects as raw text files.
Using a text editor that can search within files recursively under a folder(like the free Notepad++ for instance) I am then confident that I find all occurrences, however buried, of a particular string.
The Code for exporting all objects includes my IsBlank() function:
'====================================================================
' Name: DocDatabase
' Purpose: Documents the database to a series of text files
' From: http://www.datastrat.com/Code/DocDatabase.txt
' Author: Arvin Meyer
' Date: June 02, 1999
' Comment: Uses the undocumented [Application.SaveAsText] syntax
' To reload use the syntax [Application.LoadFromText]
' Modified to set a reference to DAO 8/22/2005
' Modified by Renaud Bompuis to export Queries as proper SQL
'====================================================================
Public Sub DocDatabase(Optional path As Variant = Null)
If IsBlank(path) Then
path = Application.CurrentProject.path & "\" & Application.CurrentProject.Name & " - exploded view\"
End If
On Error Resume Next
MkDir path
MkDir path & "\Forms\"
MkDir path & "\Queries\"
MkDir path & "\Queries(SQL)\"
MkDir path & "\Reports\"
MkDir path & "\Modules\"
MkDir path & "\Scripts\"
On Error GoTo Err_DocDatabase
Dim dbs As DAO.Database
Dim cnt As DAO.Container
Dim doc As DAO.Document
Dim i As Integer
Set dbs = CurrentDb() ' use CurrentDb() to refresh Collections
Set cnt = dbs.Containers("Forms")
For Each doc In cnt.Documents
Application.SaveAsText acForm, doc.Name, path & "\Forms\" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Reports")
For Each doc In cnt.Documents
Application.SaveAsText acReport, doc.Name, path & "\Reports\" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Scripts")
For Each doc In cnt.Documents
Application.SaveAsText acMacro, doc.Name, path & "\Scripts\" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Modules")
For Each doc In cnt.Documents
Application.SaveAsText acModule, doc.Name, path & "\Modules\" & doc.Name & ".txt"
Next doc
Dim intfile As Long
Dim filename as String
For i = 0 To dbs.QueryDefs.count - 1
Application.SaveAsText acQuery, dbs.QueryDefs(i).Name, path & "\Queries\" & dbs.QueryDefs(i).Name & ".txt"
filename = path & "\Queries(SQL)\" & dbs.QueryDefs(i).Name & ".txt"
intfile = FreeFile()
Open filename For Output As #intfile
Print #intfile, dbs.QueryDefs(i).sql
Close #intfile
Next i
Set doc = Nothing
Set cnt = Nothing
Set dbs = Nothing
Exit_DocDatabase:
Debug.Print "Done."
Exit Sub
Err_DocDatabase:
Select Case Err
Case Else
MsgBox Err.Description
Resume Exit_DocDatabase
End Select
End Sub
To use it, just call DocDatabase from the Immediate window in the Access IDE, it will create a set of directories under and 'Exploded View' folder that will contain all the files.
Another option is to temporarily turn on the NAME AUTOCORRECT option. It's a badly implemented feature and can damage your database if left on for production deployment, but I very often use it when taking over an Access app created by somebody else in order convert it to use my naming conventions.
You basically turn it on, let it build the dependencies table, then make your changes. You can then walk the tree of dependencies to confirm that it got them all. When you're done, you turn it off.
However, it doesn't work for VBA code. But for changing field names and the like, it's pretty useful if used carefully.
I amended the code above to strip out temporary objects with "~" in the object name as follows:
Set cnt = dbs.Containers("Scripts")
For Each doc In cnt.Documents
If Not doc.Name Like "~*" Then
Application.SaveAsText acMacro, doc.Name, path & "\Scripts\" & doc.Name & ".txt"
End If
Next doc