VBA code to combine powerquery tables into one new table - vba

Ok, here's my issue, I managed to dynamicly load new tables into the powerquery datamodel.
I would like to combine all these tables into one new one called Allcontrols.
My approach is to try a for each loop and add every new table seperatly.
So far I am getting an error in m om the code in the combine tables section. Help is much appreciated.
Sub Add_Connection_All_Tables()
'Creates Connection Only Queries to all tables in the active workbook.
Dim wb As Workbook
Dim ws As Worksheet
Dim lo As ListObject
Dim sName As String
Dim sFormula As String
Dim wq As WorkbookQuery
Dim bExists As Boolean
Dim vbAnswer As VbMsgBoxResult
Dim vbDataModel As VbMsgBoxResult
Dim i As Long
Dim dStart As Double
Dim dTime As Double
Dim cn As WorkbookConnection
Unprotectwb
UnprotectSh
'Set variables
Set wb = ActiveWorkbook
'Clear connections
On Error Resume Next
For Each cn In ThisWorkbook.Connections
cn.Delete
Next
'Clear queries
For Each wq In wb.Queries
wq.Delete
Next wq
'Loop sheets and tables
For Each ws In ActiveWorkbook.Worksheets
For Each lo In ws.ListObjects
sName = lo.Name
If Left(sName, 3) Like "WP_" Then
sFormula = "Excel.CurrentWorkbook(){[Name=""" & sName & """]}[Content]"
'Check if query exists
bExists = False
For Each wq In wb.Queries
If InStr(1, wq.Formula, sFormula) > 0 Then
bExists = True
End If
Next wq
'Add query if it does not exist
If bExists = False Then
'Add query
wb.Queries.Add Name:=sName, _
Formula:="let" & Chr(13) & "" & Chr(10) & " Source = Excel.CurrentWorkbook(){[Name=""" & sName & """]}[Content]" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " Source"
'Add connection
wb.Connections.Add2 Name:="Query - " & sName, _
Description:="Connection to the '" & sName & "' query in the workbook.", _
ConnectionString:="OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & sName & ";Extended Properties=""""", _
CommandText:="SELECT * FROM [" & sName & "]", _
lCmdtype:=2, _
CreateModelConnection:=False, _
ImportRelationships:=False
'Add to datamodel
wb.Connections.Add2 Name:="Query - " & sName, _
Description:="Connection to the '" & sName & "' query in the workbook.", _
ConnectionString:="OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & sName & ";Extended Properties=", _
CommandText:="" & sName & "", _
lCmdtype:=6, _
CreateModelConnection:=True, _
ImportRelationships:=False
'Combine tables section
ActiveWorkbook.Queries.Add Name:="Allcontrols", Formula:= _
"let" & Chr(13) & "" & Chr(10) & " Source = Table.Combine({""" & sName & """})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " Source"
End If
End If
Next lo
Next ws
'Protectwb
'ProtectSh
End Sub

Related

Excel VBA Save path/name from cells with variables

I am using cells as the file path and filename to save a copy of my workbook.
Here's the code am using now but it puts spaces in between each cell.
Note only the ActiveSheet.Range cells will have the possibility of being blank
Dim NewWb As Workbook
sFile = Control_Sheet_VB.Range("H2") & "\" & ActiveSheet.Range("H8") & " " & ActiveSheet.Range("E10") & " " & ActiveSheet.Range("D14") & " - Ticket #" & Control_Sheet_VB.Range("B2") & Control_Sheet_VB.Range("C2") & ".xlsm"
Set OldWb = ActiveWorkbook
OldWb.SaveCopyAs sFile
Set NewWb = Workbooks.Open(sFile)
How can I make it so if some of the cells that are used as the file name are blank then it dose not put the extra space in the filename
you may go like this:
sFile = Control_Sheet_VB.Range("H2") & "\" & _
IIf(ActiveSheet.Range("H8") <> "", ActiveSheet.Range("H8") & " ", "") & _
IIf(ActiveSheet.Range("E10") <> "", ActiveSheet.Range("E10") & " ", "") & _
IIf(ActiveSheet.Range("D14") <> "", ActiveSheet.Range("D14") & " ", "") & _
" - Ticket #" & Control_Sheet_VB.Range("B2") & _
Control_Sheet_VB.Range("C2") & ".xlsm"

Getting a subscript out of range error on list object

So, I've been working on a code that allows editing of database tables via excel, and I've run into a snag with a table object.
The code is written almost the exact same way on other worksheets, but for some reason, only this worksheet gives me the subscript out of range error when setting the list object. I've check the name of the table and tried changing it a couple of times. What am I missing?
Here's the code so far:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim CustomersConn As ADODB.Connection
Dim CustomersCmd As ADODB.Command
Dim lo As Excel.ListObject
Dim ws As Excel.Worksheet
Dim lrs As Range
Dim lr As Excel.ListRow
Dim Customers As Variant
Dim areaCount As Integer
Dim i As Integer
Dim Rows As Range
Dim rRow As Range
Dim lRows As Excel.ListRows
Dim Counter As Double
Set ws = ThisWorkbook.Worksheets(11)
Set lo = ws.ListObjects("TProspects")
Set CustomersConn = New ADODB.Connection
Set CustomersCmd = New ADODB.Command
Set lrs = Target
For Each Rows In lrs.Rows
On Error GoTo jmp
'========Section 1===========
If Counter < 1 Then
Intersect(lr.Range, lo.ListColumns("ID").Range).Value = WorksheetFunction.Max(lo.ListColumns("ID").Range) + 1
End If
'^^^^^^^^Section 1^^^^^^^^^^^
Set lr = lo.ListRows(Rows.Row - 5)
CustomersConn.ConnectionString = SQLConStr
CustomersConn.Open
CustomersCmd.ActiveConnection = CustomersConn
CustomersCmd.CommandText = _
GetUpdateText( _
Intersect(lr.Range, lo.ListColumns("ID").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Prospect").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Contact").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Email").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Phone").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Address").Range).Value, _
Intersect(lr.Range, lo.ListColumns("City").Range).Value, _
Intersect(lr.Range, lo.ListColumns("State").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Zip").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Buying Group").Range).Value, _
Intersect(lr.Range, lo.ListColumns("Type").Range).Value)
CustomersCmd.Execute
Next Rows
CustomersConn.Close
Set CustomersConn = Nothing
Set lo = Nothing
Set ws = Nothing
Set lr = Nothing
Application.Calculation = xlCalculationAutomatic
jmp:
End Sub
GetUpdateText function:
Function GetUpdateText(ID As Double, Prospect As String, Contact As String, Email As String, Phone As String, Address As String, City As String, State As String, Zip As Double, Corp As String, CType As String) As String
Dim SQLStr As String
SQLStr = _
"UPDATE Prospect" & _
" SET Type = '" & CType & "'," & _
"Prospect = '" & Replace(Prospect, "'", "''") & "'," & _
"Contact = '" & Contact & "'," & _
"Email = '" & Email & "'," & _
"Phone = '" & Phone & "'," & _
"Address = '" & Address & "'," & _
"City = '" & City & "'," & _
"State = '" & State & "'," & _
"Zip = " & Zip & "," & _
"[Buying Group] = '" & Corp & "'" & _
"WHERE ID = " & ID & _
"IF ##ROWCOUNT=0" & _
"INSERT INTO Prospect (" & _
"Type,Contact,Prospect,Email,Phone,Address,City,State,Zip,[Buying Group])" & _
"VALUES (" & _
"'" & CType & "'," & _
"'" & Contact & "'," & _
"'" & Replace(Prospect, "'", "''") & "'," & _
"'" & Email & "'," & _
"'" & Phone & "'," & _
"'" & Address & "'," & _
"'" & City & "'," & _
"'" & State & "'," & "'" & Zip & "'," & "'" & Corp & "')"
GetUpdateText = SQLStr
End Function
Matt Cremeens and Andrew Wynn brought up a valid point which directed me to where I needed to be.
While I did indeed have the table on sheet index 11, for what ever reason, utilizing the name of the sheet instead of the index value worked. I totally forgot that Worksheets is an associative array. As far as why the index did not work, it's a total mystery.

VBA using multiple Application.OnTime; one seems to fail

This is part of a much larger macro that has multiple instances of Application.OnTime that work just fine.
My issue with this one below is in WaitForPriceVolume() when it gets to the For Each loop and the If is true, it doesn't go back to the procedure WaitForPriceVolume(). It circles back to all the procedures that were called before, effectively just doing the Exit Sub as if the OnTime didn't exist.
When I strip out just the below code and add fixed values for the global variables being used, the Application.OnTime works. It's only when I plug it back into the bigger macro.
Sub BDP_PriceVolume()
Dim lsStartRange As String
Dim lsEndRange As String
Dim lnStartRow As Long
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Set sht = Worksheets("Variables")
' Use gvList
lsStartRange = "C" & gnStartRow
lnStartRow = gnStartRow + UBound(gvList, 2)
lsEndRange = "C" & lnStartRow
sht.Range(lsStartRange & ":" & lsEndRange).Value = _
"=BDP($A" & gnStartRow & "&Variables!$A$2,Variables!$D$2)"
lsStartRange = "D" & gnStartRow
lsEndRange = "D" & lnStartRow
If Worksheets("Variables").Cells(3, 3).Value <> "" Then
sht.Range(lsStartRange & ":" & lsEndRange).Value = _
"=BDH($A" & gnStartRow & "&Variables!$A$2,Variables!$E$3" & "," & _
"Variables!$B$4,Variables!$C$3," & _
Chr(34) & "BarTp=T" & Chr(34) & "," & _
Chr(34) & "BarSz=40" & Chr(34) & "," & _
Chr(34) & "Dir=V" & Chr(34) & "," & _
Chr(34) & "Dts=H" & Chr(34) & "," & _
Chr(34) & "Sort=A" & Chr(34) & "," & _
Chr(34) & "Quote=C" & Chr(34) & "," & _
Chr(34) & "UseDPDF=Y" & Chr(34) & ")"
Else
sht.Range(lsStartRange & ":" & lsEndRange).Value = _
"=BDP($A" & gnStartRow & "&Variables!$A$2,Variables!$E$2)"
End If
sht.Range("C" & gnStartRow & ":" & lsEndRange).Select
Application.Run "RefreshCurrentSelection"
Application.OnTime Now + TimeValue("00:00:03"), "WaitForPriceVolume"
End Sub
Private Sub WaitForPriceVolume()
Dim rng As Range
Set rng = sht.Range("C" & gnStartRow & ":D" & fnLastRow(sht, "A"))
Dim cell As Range
Application.ScreenUpdating = True
For Each cell In rng
If cell.Value = "#N/A Requesting Data..." Then
Application.OnTime Now + TimeValue("00:00:03"), "WaitForPriceVolume"
Exit Sub
End If
Next cell
Call DoneWaitForPriceVolume
End Sub
Own stupidity. All the other instances of OnTime came at the end of the code, so the macro had nothing left to do until the OnTime triggered and I forced everything to circle back to the main macro. I hadn't done that in this case. Problem solved. This haunted me for a week

VBA SQL query result error

There's no result or blank excel sheet in result of following SQL query. It works fine if I remove where condition but Its required. So kindly help me to correct my code with where condition. Code is follow-
Private Sub cmdOpenQuery_Click()
Dim strTableName As String
Dim strFieldName As String
Dim strFieldValue As String
Dim strFV As String
Dim strFieldType As String
Dim strBaseSQL As String
Dim strCriteria As String
Dim varItem As Variant
Dim strSQL As String
Dim qdf As DAO.QueryDef
Dim OutPut As String
Dim intCounter As Integer
Dim xlApp As Object
For Each qdf In CurrentDb.QueryDefs
If qdf.Name = "MyQry" Then
DoCmd.DeleteObject acQuery, "MyQry"
Exit For
End If
Next
strTableName = Me.[cboSelectTblQry]
strFieldName = Me.[cboWhere]
strFV = Me.[cboEqualto]
strFieldType = CurrentDb.TableDefs(Me.cboSelectTblQry).Fields(Me.cboWhere).Type
If strFieldType = 4 Then
strFieldValue = "[" & strFV & "]"
ElseIf strFieldType = 10 Then
strFieldValue = "['" & strFV & "']"
ElseIf strFieldType = 8 Then
strFieldValue = "[#" & strFV & "#]"
End If
strBaseSQL = "SELECT "
For intCounter = 0 To lstSelectTo.ListCount
lstSelectTo.Selected(intCounter) = True
Next intCounter
For Each varItem In Me![lstSelectTo].ItemsSelected
strCriteria = strCriteria & "[" & Me![lstSelectTo].ItemData(varItem) & "],"
Next
strSQL = strBaseSQL & Left$(strCriteria, Len(strCriteria) - 1) & " FROM [" & strTableName & "]" & " Where [" & strFieldName & "] = strFieldValue "
Set qdf = CurrentDb.CreateQueryDef("MyQry", strSQL)
If cboFormat = "Excel" Then
OutPut = "D:/Export_" & strTableName & "_" & Date & ".xlsx"
DoCmd.TransferSpreadsheet acExport, , "MyQry", OutPut
MsgBox " File has been exported to " & OutPut
DoCmd.Close
DoCmd.OpenForm "frmCreateQry"
Set xlApp = CreateObject("Excel.Application")
xlApp.Workbooks.Open (OutPut)
xlApp.Visible = True
ElseIf cboFormat = "PDF" Then
OutPut = "D:/Export_" & strTableName & "_" & Date & ".pdf"
DoCmd.OutputTo acOutputQuery, "MyQry", acFormatPDF, OutPut, True
MsgBox " File has been exported to " & OutPut
ElseIf cboFormat = "Word" Then
End If
ExitSub:
Exit Sub
ErrorHandler:
Resume ExitSub
End Sub
Your where condition is using strFieldValue as the value to look for. You should instead use the use held by strFieldValue for comparison. You're doing that properly with strTableName already. It is the same idea here. You'd need to enclose the value of strFieldValue in quotes when you add it.
strSQL = strBaseSQL & Left$(strCriteria, Len(strCriteria) - 1) & " FROM [" & strTableName & "]" & " Where [" & strFieldName & "] = '" & strFieldValue & "'"
I made some corrections and it's working now fine for all format like numeric, text and date type.
Following corrections made in Type condition :-
If strFieldType = 4 Then
strFieldValue = Me.cboEqualto
ElseIf strFieldType = 10 Then
strFieldValue = "'" & strFV & "'"
ElseIf strFieldType = 8 Then
strFieldValue = "#" & strFV & "#"
End If
and following correction in strSQL:-
strSQL = strBaseSQL & Left$(strCriteria, Len(strCriteria) - 1) & " FROM [" & strTableName & "]" & " Where [" & strFieldName & "] = " & strFieldValue & ""

Update four links in a workbook

I am attempting to update four links in a workbook that I have created. I have pieced together the following code using what I found online. The links that I am trying to replace have dynamic file names based on date and state. I was hoping that excel orders link names the same way they are ordered in the edit links window. It appears this is not the case.
The issue I am having is that the link that I intended to be varlink(1) is being replaced by the one that is meant to replace varlink(4). Is there anyway to ensure I replace the "loss" link with the "loss" link, etc.?
Sub UpDateLinks()
Dim Date1 As String
Dim StateAbbrev As Variant
Dim varLinks As Variant
Dim i As Integer
Sheets("Inputs").Select
ActiveSheet.Range("StateAbbrev").Activate
StateAbbrev = ActiveCell.Value
Date1 = Range("AD1")
varLinks = ActiveWorkbook.LinkSources(xlExcelLinks)
ActiveWorkbook.ChangeLink _
Name:=varLinks(1), NewName:="F:\MyHouse\" & Date1 & "\" & StateAbbrev & "\Home\" & StateAbbrev & " Loss Trends " & Date1 & ".xlsm", _
Type:=xlExcelLinks
ActiveWorkbook.ChangeLink _
Name:=varLinks(2), NewName:="F:\MyHouse\" & Date1 & "\" & StateAbbrev & "\Home\" & StateAbbrev & " Prem Trends " & Date1 & ".xlsm", _
Type:=xlExcelLinks
ActiveWorkbook.ChangeLink _
Name:=varLinks(3), NewName:="F:\MyHouse\" & Date1 & "\" & StateAbbrev & "\Home\" & StateAbbrev & " Fast Track Loss Trends " & Date1 & ".xlsm", _
Type:=xlExcelLinks
ActiveWorkbook.ChangeLink _
Name:=varLinks(4), NewName:="F:\MyHouse\" & Date1 & "\Home\" & StateAbbrev & " Section A " & Date1 & "-Revised.xlsx", _
Type:=xlExcelLinks
End Sub
If you loop through each of the links and use a Select Case to determine which link you are working with, you can then determine the right link to change.
See the code below that I modified based on what you have in your OP.
Sub UpDateLinks()
Dim Date1 As String
Dim StateAbbrev As String, sLink As String, sNewName as String
Dim varLinks As Variant
Dim i As Integer
Dim ws As Worksheet
Set ws = Sheets("Inputs")
With ws
StateAbbrev = .Range("StateAbbrev")
Date1 = .Range("AD1")
End With
varLinks = ActiveWorkbook.LinkSources(xlExcelLinks)
For i = 1 To UBound(varLinks)
Dim x As Integer
If InStr(1, varLinks(i), "Loss Trends") Then sLink = "Loss Trends"
If InStr(1, varLinks(i), "Prem Trends") Then sLink = "Prem Trends"
If InStr(1, varLinks(i), "Fast Track Loss Trends") Then sLink = "Fast Track Loss Trends"
If InStr(1, varLinks(i), "Section A") Then sLink = "Section A"
sNewName = "F:\MyHouse\" & Date1 & "\" & StateAbbrev & "\Home\" & StateAbbrev & " " & sLink & " " & Date1 & ".xlsm"
If sLink = "Section A" Then sNewName = Replace(sNewName,".xlsm","-Revised.xlsm")
ActiveWorkbook.ChangeLink _
Name:=varLinks(i), NewName:=sNewName, Type:=xlExcelLInks
Next
End Sub