I've recorded a macro to query a database, and when I record the macro, the query runs properly. However, when I try to run the macro again on the same sheet or on a different one, I get the error:
runtime error 1004, "SQL syntax error"
on the line
.Refresh BackgroundQuery:=False".
Below is the recorded macro.
Sub Macro3()
With ActiveSheet.QueryTables.Add(Connection:= _
"ODBC;DSN=Substation Prod;SRVR=SUBP;UID=U326357;", Destination:=Range("A1"))
.CommandText = Array( _
"SELECT FACT_MONTHLY.TIME_STAMP, FACT_MONTHLY.SYSTEM_NUMBER_VAL0, FACT_MONTHLY.SUBSTATION_NUMBER_VAL0, FACT_MONTHLY.MVA_MAX_OUT_VAL0, FACT_MONTHLY.MW_MAX_OUT_VAL0, FACT_MONTHLY.MVAR_MAX_OUT_VAL0, FACT_" _
, _
"MONTHLY.MW_MIN_OUT_VAL0, FACT_MONTHLY.MVAR_MIN_OUT_VAL0, FACT_MONTHLY.PF_MAX_VAL0, FACT_MONTHLY.PF_MIN_VAL0, FACT_MONTHLY.TOP_OIL_TANK_MAX_VAL0, FACT_MONTHLY.LOAD_FACTOR_VAL0, FACT_MONTHLY.PH1_TAP_MAX" _
, _
"_DRAG_VAL0, FACT_MONTHLY.WIND_TEMP_MAX_VAL0, FACT_MONTHLY.LTC_TEMP_MAX_VAL0, FACT_MONTHLY.PH2_TAP_MAX_DRAG_VAL0, FACT_MONTHLY.PH3_TAP_MAX_DRAG_VAL0, FACT_MONTHLY.BOT_OIL_TEMP_MAX_VAL0, FACT_MONTHLY.PH" _
, _
"1_TAP_MIN_DRAG_VAL0, FACT_MONTHLY.PH2_TAP_MIN_DRAG_VAL0, FACT_MONTHLY.PH3_TAP_MIN_DRAG_VAL0, FACT_MONTHLY.PH1_LOAD_MAX_KV_VAL0, FACT_MONTHLY.PH2_LOAD_MAX_KV_VAL0, FACT_MONTHLY.PH3_LOAD_MAX_KV_VAL0, FA")
.Name = "Query from Substation Prod"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.Refresh BackgroundQuery:=False
End With
End Sub
I've searched online for ways to fix this issue, but none of the other solutions I've found are working. Any help would be greatly appreciated.
All the previous lines inside the With statement are setting properties.
the
.Refresh BackgroundQuery := False
is a method call.
The refresh is supposed to refresh the results.
The background Query is for when quering SQL data and is optional so I think you can leave it off and just have .Refresh
For further assistance try VBA Excel QueryTables.add .Refresh BackgroundQuery Error
Related
In order to have the completed SQL i stored it at one of the worksheets then extract from there, but having error if the statement too long as the vba not able to capturing the full SQL code (if the filter data is not alot it works fine). Im very new to use the SQL in the VBA and hope if there any way can solve for this
Please refer below code that i have created, Thanks. It will stop at the Commandtext = Array(SQLCODE) when requested too many data. Thanks
CODE1 = Worksheets("Sheet1").Range("A6")
SQLCODE = CODE1
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
"ODBC;DSN=EBT-RAW;UID=00174;Trusted_Connection=Yes;APP=Microsoft Office 2016;WSID=SNG-LP-0153;DATABASE=EBTRawConsumption" _
, Destination:=Range("$A$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array(SQLCODE)
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.ListObject.DisplayName = "Table_Query_from_EBT_RAW"
.Refresh BackgroundQuery:=False
End With
This is SQLCODE
Select * FROM EBTRawConsumption.dbo.AMI_UsageData
WHERE UsageDate >= '2019-6-1'and UsageDate <= '2019-7-1'
and MeterID in ('','000572992','000674117','000685835','000680646','000681342','000697973','000697890','000728193','000728213','000730270','000730266','000730800','000730267','000732442','000731276','000730869','000731890','000731592','000735403','000737161','000737976','000739532','000738001','000737581','000737596','000737996','000738298','000737587','000738840','000739370','000739367','000736241','000737089','000738970','000740763','000742172','000746989','000750232','000749300','000749303','000749179')
I am trying to write some VBA that will import some data into a query table using a .odc file that is stored in a SharePoint data connection library. I used the macro recorder to record the process where I add the connection, then go to the existing connections and import the data into a table in the current worksheet(which worked when I did it manually).
The recorder spit out the following code (I removed the command text since it contains some sensitive info, but it was a big string of SharePoint related stuff like the list and view GUID):
Sub RecordedImportMacro()
Workbooks("MyWorkbook.xlsm").Connections.AddFromFile _
"http://path/to/my/odcfile/on/sharepoint.odc"
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
"OLEDB;Provider=Microsoft.Office.List.OLEDB.2.0;Data Source="""";ApplicationName=Excel;Version=12.0.0.0" _
, Destination:=Range("$A$1")).QueryTable
.CommandType = 5
.CommandText = "some command text here"
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.SourceConnectionFile = "http://path/to/my/odcfile/on/sharepoint.odc"
.ListObject.DisplayName = "My_Table"
End With
End Sub
However, when I run the macro to seemingly perform the exact same task that worked before I get the following error: Run time error 1004. I googled and it didn't really find anything that pertained to my use case
when I debug the following line is highlighted: .CommandType = 5
Any ideas on how to get this working?
I was able to get it working using code found here
Below is the code:
Sub ThisWorks()
With ActiveSheet.QueryTables.Add(Connection:= _
"FINDER;http://path/to/my/odcfile/on/sharepoint.odc" _
, Destination:=Range("$A$1"))
.RefreshStyle = xlInsertDeleteCells
.RowNumbers = False
.FillAdjacentFormulas = False
.RefreshOnFileOpen = True
.HasAutoFormat = True
.BackgroundQuery = True
.TablesOnlyFromHTML = True
.Refresh BackgroundQuery:=False
.SavePassword = False
.SaveData = True
End With
End Sub
so in all my VBA macros that use SQL to query our database, I have just been using what is automatically entered when recording a macro in Excel. Is there a way to simplify it? It inserts it into a table first, but really I just want to the raw data in a spreadsheet... it doesn't need to look nice.
Sheets("Sheet1").Select
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:="ODBC;DSN=AS400;" _
, Destination:=Range("$A$1")).QueryTable
.CommandText = strSQL
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.ListObject.DisplayName = "Table_LOCAL_ITEM"
.Refresh BackgroundQuery:=False
End With
ActiveSheet.ListObjects("Table_LOCAL_ITEM").Unlist
Cells.Select
Selection.ClearFormats
I cannot remember the exact code, but can look it up when I get to work again. But depending on which method you use to fetch the data in your SQL (e.g. ADO or DAO), I would do it something like this, if I just wanted the raw data.
If you define a variable as your recordset (for example Dim rst as recordset), VBA has a function to return all data from your recordset, something like:
Sheets("Sheet 1").Range("A1").CopyFromRecordset rst
Which will output all the data from the recordset.
Sub Macro1()
Dim URL As String
Dim Path As String
Dim i As Integer
For i = 2 To 50
If Range("Prices!E" & i).Value <> 1 Then
URL = Range("Prices!D" & i).Text
Path = Range("Prices!F" & i).Text
End If
Sheet19.Activate
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;" & URL _
, Destination:=ActiveSheet.Range("$A$1"))
.Name = _
"" & Path
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
//'In the Line above the above
//'Run time error '1004
//'An unexpected error has occured
End With
Next i
End Sub
The code above creates an error at the specified line. A google search on .Refresh BackgroundQuery shows that it is picky in its functionality in loops. Simply deleting the line makes nothing show up in excel.
With the current error message the code works fine for the first i value and then breaks.
For Answer and comments-
TLDR: .Refresh BackgroundQuery:=False will fail if your query input is invalid or malformed. The problem in this case was the for...next loop was calling cells to use as url's that hand no values in them. However it will fail anytime the query is malformed.
All the previous lines inside the With statement are setting properties.
the .Refresh BackgroundQuery := False is a method call.
The refresh is supposed to refresh the results.
The background Query is for when quering SQL data and is optional so I think you can leave it off and just have .Refresh
Query Table Refresh Method Help Link
Edit
It would appear that there is something wrong with the URL and when it goes to refresh it is unable to do it. could be a proxy issue, or not connected to the network, or the URL does not exist.
The only way to resolve this issue is to delete the active query table after each iteration. A useful example solution provides:
https://social.technet.microsoft.com/Forums/office/en-US/956dc1b6-bd37-4b97-a042-ba2a37f729b6/removing-querytables-and-leaving-the-results?forum=excel
I'm not sure why my fix worked, but here it is:
I also used querytables.add within a for loop, and I was adding .asc files. This error was only popping up after the last addition--so my program essentially did what I wanted it to, but it would interrupt function. On the last run through the For loop, I removed the .Refresh BackgroundQuery:=False statement. It was necessary for it to paste my data for all the previous runs through the For loop.
Basically I replaced this:
.Refresh BackgroundQuery:=False
With this:
If Index = ctr Then
Else
.Refresh BackgroundQuery:=False
End If
Sub Macro3()
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://..." _
, Destination:=Range("Sheet6!$G$23"))
''// The line above fails with the error:
''// "Run-time error '-2147024809 (80070057)':
''// The destination range is not on the same worksheet
''// that the Query table is being created on."
.Name = _
"?tmp=toolbar_FlvTube_homepage&prt=..."
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
End Sub
The recorded macro fails as described in the comment.
You recorded the macro while Sheet 6 was active, but are now trying to run it on a different sheet. To run the macro for the current active sheet, simply change the code as follows:
Sub Macro3()
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://..." _
, Destination:=ActiveSheet.Range("$G$23"))
...
End With
End Sub
Edit: (in response to comment):
I need to be able to paste the results of the query to a different sheet then the active one since the macro can be run at any time and must be paste to the same location everytime. Perhaps there is a way to change your active sheet with code?
The error happens when the two sheets are different, so if you want the magic to happen on a particular sheet, you should specify that sheet instead of using ActiveSheet. The following code would always place the QueryTable on Sheet6:
Sub Macro3()
With Sheet6.QueryTables.Add(Connection:= _
"URL;http://..." _
, Destination:=Sheet6.Range("$G$23"))
...
End With
End Sub