Access VBA - Export .csv module, custom file name - vba

I have problem with my Access Export to .csv module. Everything works fine in other parts like importing one list, importing second list, doing query and export IF I do not change my output file name, I am lost and don't know why changing output filename cause Access to showing Error:
Runtime Error: 3027:
Cannot update. Database or object is read-only.
Everything works fine If output file stay default.
Module code below:
Public Sub exportQuery(exportSQL As String)
Dim db As DAO.Database, qd As DAO.QueryDef
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogSaveAs)
Set db = CurrentDb
'Check to see if querydef exists
For i = 0 To (db.QueryDefs.Count - 1)
If db.QueryDefs(i).Name = "tmpExport" Then
db.QueryDefs.Delete ("tmpExport")
Exit For
End If
Next i
Set qd = db.CreateQueryDef("tmpExport", exportSQL)
'Set intial filename
fd.InitialFileName = "Deduplicated list_" & Format(Date, "mmddyyy") & ".csv"
If fd.Show = True Then
If Format(fd.SelectedItems(1)) <> vbNullString Then
DoCmd.TransferText acExportDelim, , "tmpExport", fd.SelectedItems(1), True
End If
End If
'Cleanup
db.QueryDefs.Delete "tmpExport"
db.Close
Set db = Nothing
Set qd = Nothing
Set fd = Nothing
End Sub

SORRY: Didn't notice that #Andre in comment above provide me a solution. Thank You very much
Okay, I find the solution. The problem was, when You type in custom name IT MUST HAVE .csv extension. I implement function which appends filename with .csv
Function getCSVName(fileName As String) As String
Dim pos As Long
pos = InStrRev(fileName, ".")
If (pos > 0) Then
fileName = Left$(fileName, pos - 1)
End If
getCSVName = fileName & ".CSV"
End Function
And use it in Export module:
DoCmd.TransferText acExportDelim, , "tmpExport", getCSVName(fd.SelectedItems(1)), True

Looks fine and works for me locally, when I enter an easy SQL command in the code above.
I would recommend to check the SQL command which you try to execute.

Related

How to build a variable filepath as link or path in MS ACCESS using VBA

I have the following problem in MS ACCESS:
Using VBA, a PDF-file is stored in the OneDrive folder and synchronized with Sharepoint. As known, OneDrive is declared as a kind of another drive on all computers in the same way.
After saving, the file is located on computer01 in the folder:
C:\Users\User01\OneDrive - AllFolders\SharedFolder\AllDocs\Doc01.pdf =>( \USER01 )
Now user02 on computer02 who is also connected to the folder wants to open the file via VBA. The path of the file in the shared table field is accordingly:
C:\Users\User01\OneDrive - AllFolders\SharedFolder\AllDocs\Doc01.pdf
Of course User02 can't open the file via VBA, because the path should be:
C:\Users\User02\OneDrive - AllFolders\SharedFolder\AllDocs\Doc01.pdf =>( \USER02 )
For example I tried to use such a path to save the file (this is not the correct Syntax!):
(Environ("USERPROFILE")) & "\OneDrive - AllFolders\SharedFolder\AllDocs\Doc01.pdf
but (Environ("USERPROFILE")) as table.field.value is of course understood as string and not as variable!
How can this problem be solved? Thanks!
my Code:
Option Compare Database
Option Explicit
Public OneDriveDirectory As String
Public Function SetPathToOneDrive() As String
SetPathToOneDrive = (Environ("USERPROFILE")) & "\OneDrive - AllFolders\SharedFolder\AllDocs\"
End Function
Sub SaveDoc()
Dim xSource As String, xDestination As String, xFilename As String
Dim FSO As Object
Dim db As DAO.Database
Dim rs As DAO.Recordset
OneDriveDirectory = SetPathToOneDrive
xFilename = "Doc01.pdf"
xSource = (Environ("USERPROFILE")) & "\" & xFilename
xDestination = OneDriveDirectory & xFilename
Set db = CurrentDb
Set rs = db.OpenRecordset("tblDocLinks", dbOpenDynaset)
Set FSO = VBA.CreateObject("Scripting.FileSystemObject")
Call FSO.CopyFile(xSource, xDestination)
With rs
.AddNew
.Fields("fldDocPath") = xDestination
.Update
End With
rs.close
db.close
End Sub
With
SetPathToOneDrive = Environ$("%UserProfile%") & "\OneDrive - All Folders\SharedFolder\AllDocs\"
you should get the correct path.
Are you sure the path is correct? The default would be something like C:\Users\username\OneDrive\...
Depending on the environment it's probably not a good idea to store absolute filepaths in the database. I tend to save only the filename and build the path together in VBA, often using values grabbed from a config-table or -file.

Exporting query from MS Access to CSV, columns with lengthy text with linebreaks get cuts off

I have a MS Access file and it has a form with a button which export a named query to a CSV file. When i open the CSV to Excel, a column with lengthy text with line breaks get cuts off. When i tried to copy and then paste special as CSV on the Excel it turns out to be fine.
Here is my VBA code
Public Sub exportQuery(exportSQL As String)
Dim db As DAO.Database, qd As DAO.QueryDef
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogSaveAs)
Set db = CurrentDb
'Check to see if querydef exists
For i = 0 To (db.QueryDefs.Count - 1)
If db.QueryDefs(i).Name = "tmpExport" Then
db.QueryDefs.Delete ("tmpExport")
Exit For
End If
Next i
Set qd = db.CreateQueryDef("tmpExport", exportSQL)
'Set intial filename
fd.InitialFileName = "export_" & Format(Date, "mmddyyy") & ".csv"
If fd.Show = True Then
If Format(fd.SelectedItems(1)) <> vbNullString Then
DoCmd.TransferText acExportDelim, , "tmpExport", fd.SelectedItems(1), False
End If
End If
'Cleanup
db.QueryDefs.Delete "tmpExport"
db.Close
Set db = Nothing
Set qd = Nothing
Set fd = Nothing
End Sub
And this for command button to call the function
Private Sub Command0_Click()
Dim queryStr As String
'Store Query Here:
queryStr = "SELECT [Name],[Notes] FROM [GetListForUpload]"
Call exportQuery(queryStr)
End Sub
Can someone help me with this?
I solved my own problem haha! So i just want to share this for any other who stumbled from this situation. Their's this hidden system objects that you want to show up in navigation options. So first is you check to show the hidden system objects in the navigation options and you will see tables that is greyed out ex.(MSysIMEXColumns, MSysIMEXSpecs) then create a specification. Open the table MSysIMEXColumns, you will see all of the field names on the specification you've created. So on my part i have Notes column which contains lenghty texts with linebreaks. In the MsysIMEXColumns table, I changed the DataType for the fieldname Notes from 10 (Text) to 12 (Memo) and voila. No lenghty texts get cuts off or truncated anymore :)
PS: If you have more than 1 specifications created please identify the specid first from MSysIMEXSpecs and then check it in MSysIMEXColumns before you changed anything for not to get confused.

Transfer Spreadsheet to Access Database with VBA

I have a browse button and pick and place the file name and path in textbox5. I need to use the same value in my file name but it does not work. It throws:
Run Time Error 2522- The action or method requires a File Name argument
Private Sub Command10_Click()
Dim dbs As DAO.Database
Dim td As DAO.TableDef
Dim fileName As String
'set current database
Set dbs = CurrentDb
Me.Text5 = fileName
DoCmd.TransferSpreadsheet acImport, , "tblS3DimportTemp", fileName, True
MsgBox "Data Uploaded!"
End Sub
Instead of: Me.Text5 = fileName
write:
fileName = Me.Text5
In many programming languages the left variable gets the value of the right one.

Importing text files - Vb/Access

What I am trying to do is map my button (import button on my form) to import text files (the text file would actually be on a network drive). These text files are fixed columns. I am confused on how to merge a form and module to work together. How does the button on the form, call out this module for execution? Also, if there is a more efficient way to import these fixed text files, I would appreciate it.
I currently have the following VBA code setup for my form (will be used to Import text files into my Access database):
Private Sub cmdImport_Click()
On Error GoTo Click_Err
reportDate = Format(txtReportDate, "YYMMDD")
reportGenDate = Format(textReportDate, "YYYYMMDD")
rDate = txtReportDate
If Nz(txtReportDate, "") = "" Then
MsgBox "NOTICE! Please enter the Report Month you wish to Import."
Exit Sub
End If
DoCmd.Hourglass True
DoCmd.SetWarnings False
ImportAll
DoCmd.Hourglass False
DoCmd.SetWarnings True
MsgBox "Finished Importing!"
DoCmd.OpenQuery "query_Files_Loaded_CE", acViewNormal, acReadOnly
click_Exit:
DoCmd.Hourglass False
DoCmd.SetWarnings True
Exit Sub
Click_Err:
DoCmd.Hourglass False
MsgBox "Error Detected: " & Err.Number & " - " & Err.Description, vbCritical, "Error"
Resume click_Exit
End Sub
For my module (please excuse the notes):
Option Compare Database
Public reportDate As String
Public reportGenDate As String
Public rDate As Date
Public Function Import2010()
'Used to import a date range
Dim funcDate As Date '
funcDate = #2/1/2016#
reportDate = Format(funcDate, "YYMM")
rDate = funcDate
'Basically Do While is a loop so what your doing here as long as the value of the date does not EQUAL 3/1/2016
'excute the nexxt line of code other wise exit this loop
Do While funcDate <> #3/1/2016#
DoCmd.SetWarnings False
'ImportAll
ImportFile "H3561"
'Msg Box reportDate
funcDate = DateAdd("m", 1, funcDate)
reportDate = Format(funcDate, "YYMM")
rDate = funcDate
Loop
DoCmd.SetWarnings True
End Function
Public Function ImportAll() ' Import button on FrmIMport
'A recordset is a selection of records from a table or query.
'Dim is short for the word Dimension and it allows you to declare variable names and their type.
'When you read data from the database in VBA, the result will be in a recordset (with the exception of scalar data).
Dim rs As Recordset
Dim sql As String
'This code loops through the recordset of all contracts and import files, as in it looks for
'Specific value based off a specific condition.
sql = "SELECT DISTINCT Contract FROM Contract_CE"
Set rs = CurrentDb.OpenRecordset(sql)
rs.MoveLast 'This method is used to move to the last record in a Recordset object. It also makes the last record the current record.
rs.MoveFirst 'This method is used to move to the first record in a Recordset object. It also makes the first record the current record.
If rs.RecordCount > 0 Then
Do While rs.EOF = False
ImportFile rs!contract
rs.MoveNext 'This method is used to move to the next record in a Recordset object. It also makes the "next" record the current record.
Loop
End If
End Function
Public Function ImportFile(contract As String)
Dim filepath As String
Dim tempPath As String
Dim zipFile As String
'Set paths
filepath = "\\XXXXX\XXXXX\XXXXX\XXXXXXX"
'tempPath =
tempPath = "\\XXXXXX\XXXXX\XXXXX\XX"
'Find the file
zipFile = GetFile(filepath)
'check if file exists
If zipFile = "" Then
'DoCmd.Hourglass False
'MsgBox contract & " " & reportDate & " File could not be located."
'DoCmd.Hourglass True
LogFail (contract)
Exit Function
End If
'Clearing out existing Contract/ReportDate data from Table
DeleteContract (contract)
'Delete all files in temp folder
DeleteAllFiles (tempPath)
'UnzipFile txt to temp folder
UnZip filepath & zipFile, tempPath
'Get txt file namee
txtFile = Replace(zipFile, ".zip", ".txt")
DoEvents
Sleep 10000 'wait for file to unzip
'The TransferText method is used to import/export text between the current Access database or Access project and a text file located
'externally to your database. You can also use this command to link to data in a text file. Additionally, can import from, export to, and link to a table in an HTML file.
'Importing txt file
'Depcreated - Alec Johnson - 5/12/2016 - Created new import spec
'DoCMD.TransferText acImportFixed, "ImportSpec_COMPRPT", tempPath & txtfile, False
DoCmd.TransferText acImportFixed, "COMPRPT_2016", "COMPRPT_CE", filepath & txtFile, False '<--does path go here?
'Update FileName
UpdateFileName (zipFile)
'Delete txt file from location
DeleteAllFiles (tempPath)
'Delete any Null records added to main table
DeleteNulls
'Log to table if successful
LogSuccess (contract)
End Function
Public Function DeleteAllFiles(path As String)
'Delete all files in this folder
On Error Resume Next
Kill path & "*.*"
End Function
Function UnZip(filename As String, destinationPath As String)
'FileSystemObject also called as FSO, provides an easy object based model to access computer’s file system.
'You simply have to create an instance of FileSystemObject in VBA and then you can generate files, read files, delete files,
'iterate though folders and do many other operations on your computer’s file system.
'Unzip file (s) to destination
Dim app As Object
Dim zipFile As Variant, unzipTo As Variant
zipFile = filename
unzipTo = destinationPath
Set FSO = CreateObject("Scripting.FileSystemObject")
If Not FSO.FolderExists(unzipTo) Then
FSO.CreateFolder (unzipTo)
End If
'If you want to extract only file you can use this:
'oApp.Namespace(FileNameFolder).CopyHere _
'oApp.Namespace(Fname).items.items("test.txt")
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(unzipTo).CopyHere oApp.Namespace(zipFile).Items
Set FSO = Nothing
End Function
Public Function GetFile(filepath As String) As String
Dim fileNamePart As String
Dim fCheck
fileNamePart = "COMPRPT_" + reportDate
fCheck = ""
fFound = ""
Set oFolder = CreateObject("scripting.filesystemobject").GetFolder(filepath)
For Each aFile In oFolder.Files
Set fCheck = aFile
If InStr(fCheck.Name, fileNamePart) Then
Set fFound = aFile
End If
Next
If fFound = "" Then
GetFile = ""
Else
GetFile = fFound.Name
End If
End Function
Public Function DeleteContract(contract As String)
Dim sql As String
sql = "Delete * FROM COMPRPT WHERE ContractNumber = '" & contract & "' AND ReportGenerationDate = '" & reportGenDate & "'"
DoCmd.RunSQL sql
End Function
Public Function LogSuccess(contract As String)
Dim sql As String
sql = "INSERT INTO FilesLoaded (Contract, ReportDate, Loaded) VALUES ('" & contract & "', #" & rDate & "#, -1)"
DoCmd.RunSQL sql
End Function
Public Function DeleteNulls()
Dim sql As String
sql = "DELETE * FROM COMPRPT WHERE ContractNumber Is Null"
DoCmd.RunSQL sql
End Function
Public Function lksjdlaskjd()
ImportFile "H0351", #4/1/2009#
End Function
Here is an example of a text file:
If I understand it correctly, your problem lies here:
DoCmd.TransferText acImportFixed, "COMPRPT_2016", "COMPRPT_CE", filepath & txtFile, False '<--does path go here?
But you have unzipped to tempPath, so that should be
DoCmd.TransferText acImportFixed, "COMPRPT_2016", "COMPRPT_CE", tempPath & txtFile, False
Working with network files is generally slower than with local files, so I would make tempPath a local path.
Edit: Note that to make tempPath & txtFile work, tempPath must end with a \:
tempPath = "C:\XXXXXX\XXXXX\XXXXX\XX\"
Additional problems with your code:
1 - First and foremost, use Option Explicit, see this question for details.
You have multiple undeclared or misspelled variables, e.g. fFound, and oApp vs. app.
2 - This is an error just waiting to happen:
reportDate = Format(txtReportDate, "YYMMDD")
reportGenDate = Format(textReportDate, "YYYYMMDD")
Name the second textbox txtReportGenDate, not textReportDate.
3 - In ImportAll(), all this isn't needed, since you don't use the RecordCount:
rs.MoveLast
rs.MoveFirst
If rs.RecordCount > 0 Then
4 - This is wrong syntax:
DeleteContract (contract)
It works for a single argument, but will fail for subs with >1 parameters.
Use
DeleteContract contract
or
Call DeleteContract(contract)
or
retVal = DeleteContract(contract)
I am confused on how to merge a form and module to work together. How does the button on the form, call out this module for execution?
Objects and procedures can be considered public or private. For example: -
Private Sub Test
Msgbox "Hello World!"
End Sub
Is private, this means only its parent can call upon it. To elaborate on this, Lets create two modules Module1 and Module2 and place our private sub Test in Module1.
Also in Module1 we another private procedure: -
Private Sub Test2
Msgbox "Back at ya"
End Sub
Module1 is the parent of Test and Test2, as they have the same parent they can run each other: -
Private Sub Test
Msgbox "Hello World!"
Test2 'This will run the Test2 procedure
End Sub
Module2 can not run any of them because it has no view f them, its not involved.
Now if we change Test to be public (Public Sub Test), Module2 will be able to see it as it has been exposed.
In Module2 we have: -
Public Sub Test3
Module1.Test 'This will run as it is public
Module1.Test2 'This will fail as it is private
End Sub
There is also this way too call them from Module two: -
Public Sub Test3
Test 'This will run as it is public
Test2 'This will fail as it is private
End Sub
This is not explicit though and can cause error and confusion, you can have a procedure in Module2 that is also called Test, how would you know which test Test3 is running? To be safe you explicit write its location as Module1.Test.

Permission Denied when running VBScript

I have a vbs script which captures file information and then exports it to a csv file. I need to run the script on main drives such as C:\, E:\, I:\ and more, but each time I run for the main directory I get "Permission Denied" when I try to run it for a subfolder example C:\Program Files it works fine. I have tested this on different desktop machines and servers with full admin accounts and still get it.
What could be the issue with this code. test.vbs
Option Explicit
Dim objFS, objFld
Dim objArgs
Dim strFolder, strDestFile, blnRecursiveSearch
Dim strLines()
Dim i
Dim strCsv
i = 0
' 'Get the commandline parameters
' Set objArgs = WScript.Arguments
' strFolder = objArgs(0)
' strDestFile = objArgs(1)
' blnRecursiveSearch = objArgs(2)
'###################################
'MAKE SURE THESE VALUES ARE CORRECT
'###################################
strFolder = "C:\"
strDestFile = "C:\Output.csv"
blnRecursiveSearch = True
'Create the FileSystemObject
Set objFS=CreateObject("Scripting.FileSystemObject")
'Get the directory you are working in
Set objFld = objFS.GetFolder(strFolder)
'Now get the file details
GetFileDetails objFld, blnRecursiveSearch
'Write the csv file
Set strCsv = objFS.CreateTextFile(strDestFile, True)
strCsv.Write Join(strLines, vbCrLf)
'Close and cleanup objects
strCsv.Close
Set strCsv = Nothing
Set objFld = Nothing
Set strFolder = Nothing
Set objArgs = Nothing
Private Sub GetFileDetails(fold, blnRecursive)
Dim fld, fil
dim strLine(5)
If blnRecursive Then
'Work through all the folders and subfolders
For Each fld In fold.SubFolders
GetFileDetails fld, True
Next
End If
'Now work on the files
For Each fil in fold.Files
strLine(0) = fil.Path
strLine(1) = fil.Type
strLine(2) = fil.Size
strLine(3) = fil.DateCreated
strLine(4) = fil.DateLastModified
strLine(5) = fil.DateLastAccessed
Redim Preserve strLines(i)
strLines(i) = Join(strLine, ",")
i = i + 1
Next
end sub
Please advise and modify code if you know where the issue is.
If it's a permissions problem I would strongly recommend Process Monitor from Sysinternals to diagnose it. You should be able to watch the cscript process (or whatever is executing your script) and find out what kind of permission problem you're having.