strQuery = _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\Source1.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
"UNION " & _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\Source2.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
"UNION " & _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\Source3.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
"ORDER BY A;"
Good morning,
I have one last nail to go on this coding I have and any help is much appreciated. I am gathering numerous files from a single folder and file names are different (although data order and data are same).
Question is:
Is it possible to get all files via the 'strQuery' without slowing down the code? How do I go on to do this? (eg: I think maybe loop but it might slow down? - see below)
Is it possible to get (say) 100 excel file data read at once? (although I do not know names of it?)
I can modify strQuery (via assigning it a text string) and input a loop to go through every file but I recon this would require me to create a connection for every single file rather than all at once?
Any help is appreciated!
Thanks in advance.
--
Full Code below (I didn't know where to put this in a visible manner)
Sub SqlUnionTest()
Dim strConnection As String
Dim strQuery As String
Dim objConnection As Object
Dim objRecordSet As Object, qText As String
strConnection = _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"User ID=Admin;" & _
"Data Source='" & ThisWorkbook.FullName & "';" & _
"Mode=Read;" & _
"Extended Properties=""Excel 12.0 Macro;"";"
Dim sFile As String
sFile = Dir(ThisWorkbook.Path & "\*.xlsx")
Do While sFile <> ""
strQuery = _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\" & sFile & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
"UNION "
sFile = Dir()
Loop
strQuery = Left(strQuery, Len(strQuery) - 7) 'to remove last UNION which is not necessary
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open strConnection
Set objRecordSet = objConnection.Execute(strQuery)
RecordSetToWorksheet Sheets(1), objRecordSet
objConnection.Close
End Sub
Sub RecordSetToWorksheet(objSheet As Worksheet, objRecordSet As Object)
Dim i As Long
With objSheet
.Cells.Delete
For i = 1 To objRecordSet.Fields.Count
.Cells(1, i).Value = objRecordSet.Fields(i - 1).Name
Next
.Cells(2, 1).CopyFromRecordset objRecordSet
.Cells.Columns.AutoFit
End With
End Sub
You can use the DIR() function to loop through all the .xlsx files in the folder without knowing the specific file names. If you need to weed out any files, you can place conditional testing inside the loop.
Code untested
Dim sFile As String, strQuery As String
sFile = Dir(ThisWorkbook.Path & "\*.xlsx")
Do While sFile <> ""
strQuery = strQuery & _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\" & sFile & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
"UNION;"
sFile = Dir()
Loop
strQuery = Left(strQuery, Len(strQuery) - 7) 'to remove last UNION which is not necessary
Related
I'm trying to run the following code, but it does not work. I receive the error "3219: Invalid Operation". I'm sure I'm missing something, and it's obvious, and I'm going to feel dumb, but I can't spot it.
In pseudocode, this is what I wish to do:
Create a Querydef for a Pass-Through query.
Use the Querydef to open a Recordset.
Check the records to be certain the query works.
If all is well, append the Querydef to Querydefs.
Here is the code:
Public Sub Test()
Dim db As DAO.Database
Dim qd As DAO.QueryDef
Dim rs As DAO.Recordset
Dim name As String
Dim conn As String
Dim sql As String
name = "TestQuery"
conn = _
"ODBC;" & _
"DRIVER={iSeries Access ODBC Driver};" & _
"UID=REMOVED;" & _
"PWD=REMOVED;" & _
"SIGNON=1;" & _
"QRYSTGLMT=-1;" & _
"PKG=QGPL/DEFAULT(IBM),2,0,1,0,512;" & _
"LANGUAGEID=ENU;" & _
"DFTPKGLIB=QGPL;" & _
"DBQ=QSYS2;" & _
"SYSTEM=REMOVED;" & _
"FILEDSN=REMOVED;"
sql = _
"SELECT TABLE_SCHEMA AS """ & "SCHEMA" & """, " & _
"TABLE_NAME AS ""TABLE"", " & _
"ORDINAL_POSITION AS ""POS"", " & _
"COLUMN_NAME AS ""COLUMN"", " & _
"DATA_TYPE AS ""TYPE"", " & _
"LENGTH AS ""LEN"", " & _
"NUMERIC_SCALE AS ""SCALE"", " & _
"COLUMN_TEXT AS ""DESCRIPTION"" " & _
"FROM QSYS2.SYSCOLUMNS " & _
"WHERE TABLE_SCHEMA='REMOVED' " & _
"AND TABLE_NAME='REMOVED'"
Set db = CurrentDb
Set qd = db.CreateQueryDef(name)
qd.Connect = conn
qd.sql = sql
Set rs = qd.OpenRecordset(DAO.RecordsetTypeEnum.dbOpenSnapshot)
If rs.RecordCount > 0 Then
'check records to see if query worked as expected
If True Then
db.QueryDefs.Append qd 'Error 3219: Invalid Operation
End If
End If
End Sub
If I modify this to read:
Dim qd As DAO.QueryDef
The OpenRecordset gives me error "3420: Object invalid or no longer set".
I have a split access database. The tables which reside in the backend have "Before Change" macros built into them (in the backend). I need to overwrite these macros with new ones. I have an XML file of the updated macro and am trying to use the code below to overwrite the macros. However, the code below puts the macro on my linked table in the frontend. I need the macro to update the macro on the table in the backend. Any and all help is much appreciated.
LoadFromText acTableDataMacro, "tblEXAMPLE", strXMLpath
I figured out how to do this.
Dim fso As Object
Dim oFile As Object
Dim strXML As String
Dim strXMLpath As String
Dim strBE As String
Dim accessApp As Access.Application
strXML = "<?xml version=" & Chr(34) & "1.0" & Chr(34) & " encoding=" & Chr(34) & "UTF-16" & Chr(34) & " standalone=" & Chr(34) & "no" & Chr(34) & "?>" & _
"<DataMacros xmlns=" & Chr(34) & "http://schemas.microsoft.com/office/accessservices/2009/11/application" & Chr(34) & "><DataMacro Event=" & Chr(34) & "BeforeChange" & Chr(34) & "><Statements><ConditionalBlock><If>"
strXMLpath = Application.CurrentProject.Path & "\XML_File.xml"
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFile = fso.CreateTextFile(strXMLpath)
oFile.WriteLine strXML
oFile.Close
Set fso = Nothing
Set oFile = Nothing
strBE = CurrentDb.TableDefs("TableName").Connect
strBE = Replace(strBE, ";Database=", "")
Set accessApp = CreateObject("Access.Application")
accessApp.OpenCurrentDatabase strBE, True
accessApp.LoadFromText acTableDataMacro, "TableName", strXMLpath
Kill strXMLpath
I found this function on GitHub and it's working great for what I need, but I can't figure out how to specify file type. It seems to default to "all".
Function BrowseForFile()
With CreateObject("WScript.Shell")
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Dim tempFolder : Set tempFolder = fso.GetSpecialFolder(2)
Dim tempName : tempName = fso.GetTempName() & ".hta"
Dim path : path = "HKCU\Volatile Environment\MsgResp"
With tempFolder.CreateTextFile(tempName)
.Write "<input type=file name=f><script>f.click()" & _
";(new ActiveXObject('WScript.Shell'))" & _
".RegWrite('HKCU\\Volatile Environment\\MsgResp', f.value)" & _
";close();<" & "/" & "script>"
.Close
End With
.Run tempFolder & "\" & tempName, 1, True
BrowseForFile = .RegRead(path)
.RegDelete path
fso.DeleteFile tempFolder & "\" & tempName
End With
End Function
'Example: msgbox BrowseForFile()
I tried modifying this line:
.Write "<input type=file name=f ><script>f.click()" & _
";(new ActiveXObject('WScript.Shell'))" & _
".RegWrite('HKCU\\Volatile Environment\\MsgResp', f.value)" & _
";close();<" & "/" & "script>"
To this:
.Write "<input type=file accept=" & chr(34) & "text/plain" & chr(34) & " name=f ><script>f.click()" & _
";(new ActiveXObject('WScript.Shell'))" & _
".RegWrite('HKCU\\Volatile Environment\\MsgResp', f.value)" & _
";close();<" & "/" & "script>"
But, still not working. Is there any way to use this function and customize the allowed file types? I want to allow only .csv, .txt, and .log
I used this function here : How to add filter to a file chooser in batch?
Function GetFileDlgEx(sIniDir,sFilter,sTitle)
Set oDlg = CreateObject("WScript.Shell").Exec("mshta.exe ""about:<object id=d classid=clsid:3050f4e1-98b5-11cf-bb82-00aa00bdce0b></object><script>moveTo(0,-9999);eval(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).Read("&Len(sIniDir)+Len(sFilter)+Len(sTitle)+41&"));function window.onload(){var p=/[^\0]*/;new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(p.exec(d.object.openfiledlg(iniDir,null,filter,title)));close();}</script><hta:application showintaskbar=no />""")
oDlg.StdIn.Write "var iniDir='" & sIniDir & "';var filter='" & sFilter & "';var title='" & sTitle & "';"
GetFileDlgEx = oDlg.StdOut.ReadAll
End Function
set fso = CreateObject("Scripting.FileSystemObject")
CurrentDirectory = fso.GetAbsolutePathName(".")
sIniDir = CurrentDirectory &"\Myfile.csv"
sFilter = "csv files (*.csv)|*.csv|txt files (*.txt)|*.txt|log files (*.log)|*.log|"
sTitle = "Put a title of your program here :) (-_°)"
MyFile = GetFileDlgEx(Replace(sIniDir,"\","\\"),sFilter,sTitle)
wscript.echo MyFile
I have an Access database with a ton of tables, forms, and queries in it. With one of my forms I have an upload button that I would like to use for appending csv files to a specific table in the database.
I have an OnClick function for the button that I am getting hung up on..
Every time it get to the line
adoCSVConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strPathToTextfile & ";" & _
"Extended Properties=""text;HDR=YES;FMT=Delimited"""
It says that: the provider cannot be found or it is not installed properly..
Does this have anything to do with the settings in the Data Source Admin settings? Am I missing a reference?
Here is all of the code if you are interested in seeing what all I have
Private Sub uploadBTN_Click()
'Dim adoCSVConnection, adoCSVRecordset, strPathToTextfile
'Dim strCSVFile, adoJetConnection, adoJetCommand, strDBPath
Dim adoCSVConnection As ADODB.Connection
Dim adoCSVRecordset As ADODB.Recordset
Dim adoJetConnection As ADODB.Connection
Dim adoJetCommand As ADODB.Command
Set adoCSVConnection = New ADODB.Connection
Const adCmdText = &H1
' Specify path to CSV file. ex: c:\Scripts\
strPathToTextfile = "C:\Desktop\"
' Specify CSV file name. ex: Users.csv
strCSVFile = "testfile2.csv"
' Specify Access database file. ex: c:\Scripts\MyData.mdb
strDBPath = "\\folder\NewMasterclient.mdb"
' Open connection to the CSV file.
Set adoCSVConnection = CreateObject("ADODB.Connection")
Set adoCSVRecordset = CreateObject("ADODB.Recordset")
' Open CSV file with header line.
adoCSVConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strPathToTextfile & ";" & _
"Extended Properties=""text;HDR=YES;FMT=Delimited"""
adoCSVRecordset.Open "SELECT * FROM " & strCSVFile, adoCSVConnection
' Open connection to MS Access database.
Set adoJetConnection = CreateObject("ADODB.Connection")
adoJetConnection.ConnectionString = "DRIVER=Microsoft Access Driver (*.mdb);" _
& "FIL=MS Access;DriverId=25;DBQ=" & strDBPath & ";"
adoJetConnection.Open
' ADO command object to insert rows into Access database.
Set adoJetCommand = New ADODB.Command
Set adoJetCommand.ActiveConnection = adoJetConnection
adoJetCommand.CommandType = adCmdText
' Read the CSV file.
Do Until adoCSVRecordset.EOF
' Insert a row into the Access database.
adoJetCommand.CommandText = "INSERT INTO testfile2" & "(a, b, c, d, clientid, reg) " & "VALUES (" _
& "'" & adoCSVRecordset.Fields("a").Value & "', " _
& "'" & adoCSVRecordset.Fields("b").Value & "', " _
& "'" & adoCSVRecordset.Fields("c").Value & "', " _
& "'" & adoCSVRecordset.Fields("d").Value & "', " _
& "'" & adoCSVRecordset.Fields("clientid").Value & "')" _
& "'" & adoCSVRecordset.Fields("reg").Value & "')"
adoJetCommand.Execute
adoCSVRecordset.MoveNext
Loop
' Clean up.
adoCSVRecordset.Close
adoCSVConnection.Close
adoJetConnection.Close
End Sub
I have a database that I am trying to send information contained on a form combined with selected items in a listbox to a table when the user clicks a Send button. I have the code setup that should copy my information but get a syntax error and I am not sure why... I have tried several different things and can't get it to work. I have included the code below:
Private Sub ctrSend_Click()
Dim intI As Integer
Dim lst As ListBox
Dim varItem As Variant
Set lst = Me![lstShipping]
With lst
If .ItemsSelected.count = 0 Then Exit Sub
For Each varItem In .ItemsSelected
CurrentDb.Execute "INSERT INTO ShipInv ([Order], [ShipDate], [BIN], [SKU], [Lot], [QtyProd])" _
"VALUES ('" & Me.[ctrSOrder] & "'," & Me.[ctrSDate] & ",'" & .Column(0, varItem) & "'," & .Column(1, varItem) & "," & .Column(2, varItem) & "," & .Column(3, varItem) & ");", dbFailOnError
Next
End With
End Sub
For a situation like this, I always reccommend using a string to hold the constructed SQL so that you can easily print the string to the immediate window to check how certain values have broken your SQL.
So, try adding
Dim strSQL As String
strSQL = "INSERT INTO ShipInv ([Order], [ShipDate], [BIN], [SKU], [Lot], [QtyProd])" _
"VALUES ('" & Me.[ctrSOrder] & "'," & Me.[ctrSDate] & ",'" & .Column(0, varItem) & "'," & .Column(1, varItem) & "," & .Column(2, varItem) & "," & .Column(3, varItem) & ");"
Debug.Print strSQL
CurrentDb.Execute strSQL 'remove dbFailOnError temporarily so that failure will stop code
My blind guess is that if ShipDate is a date field(not text), you'll need to format that value with Format(Me.[ctrSDate], "\#mm\/dd\/yyyy\#" before pasting it into the SQL.
I used a different approach and it works out great...
Private Sub ctrSend_Click()
Dim intI As Integer
Dim lst As ListBox
Dim varItem As Variant
Dim rst As DAO.Recordset
Set lst = Me![lstShipping]
Set rst = CurrentDb.OpenRecordset("ShipInv", dbOpenTable)
With lst
If .ItemsSelected.count = 0 Then Exit Sub
For Each varItem In .ItemsSelected
rst.AddNew
rst!Order = Me.[ctrSOrder]
rst!EntDate = Date
rst!ShipDate = Me.[ctrSDate]
rst!BIN = .Column(0, varItem)
rst!SKU = .Column(1, varItem)
rst!Lot = .Column(2, varItem)
rst!QtyProd = .Column(3, varItem)
rst.Update
Next
End With
rst.Close
Set rst = Nothing
MsgBox "Warehouse Inventory Updated", vbOKOnly, "Inventory Confirmation"
End Sub