Copying Worksheets with Powerquery using VBA - breaks Query - vba

I have a Worksheet called "TEMPLATE" with a PowerQuery "TEMPLATE_Query" in it which works. The Powerquery requests a CSV-file from a website.
Now, using VBA in a loop, I make N copies of this sheet, resulting in worksheets named "Template (X)" and Powerquerys named "TEMPLATE_Query (X)". X=1..N. In my VBA code, I modify the Powerquery Formulas to request a different CSV file. Until here, it works alright. The Powerquerys run and receive different CSV files in all those Worksheets.
Here's the problem:
When I change the name of the Worksheet using VBA during my loop where I create the copies, the Powerquerys fail afterwards. Saying like "Download failed, connection only". So apparently the Powerquery doesn't have a reference to the correct sheetname anymore. The same happens when I rename the Powerquery and leave the Worksheet Name the same.
My goal is, to rename the Worksheet AND the Powerquery both in my VBA loop.
But why does this break the Queries?

I had the same problem a little while ago. If I remember correctly, it breaks because the query still wants to access something with a different name. I don't know why Excel does not change the reference when you rename a query. It does not even automatically changes it if you rename it manually with a right click. If you look at the query, right click it and then switch over to properties or what ever the middle tab is called, there you can see some details.
Long story short, this is how I fixed mine:
Sub Create_new_connection()
'On Error Resume Next
'Count the current amount of queries and save that number to refer to it later
QueryCount = ThisWorkbook.Queries.Count
'Copy the template and rename it
ThisWorkbook.Sheets("Template").Copy after:=ThisWorkbook.Sheets("Template")
ThisWorkbook.Sheets(3).Name = "Put a name here"
'Change the name of the query
ThisWorkbook.Queries.Item(QueryCount + 1).Name = "New Query Name"
'Change the names of the new table
ThisWorkbook.Sheets(3).ListObjects(1).Name = "I had a table I wanted to rename"
'Change the formula of the new connection
NewFormula = Replace(ThisWorkbook.Queries.Item(1).Formula, ThisWorkbook.Sheets("Create New List").ListObjects("Template").DataBodyRange(1, 1), ThisWorkbook.Sheets("Create New List").ListObjects("FAUF").DataBodyRange(1, 1))
ThisWorkbook.Queries.Item(QueryCount + 1).Formula = NewFormula
'Connect the new table to the new connection and
ThisWorkbook.Sheets(3).ListObjects(1).QueryTable.WorkbookConnection = "Abfrage - " & ThisWorkbook.Queries.Item(QueryCount + 1).Name
ThisWorkbook.Sheets(3).ListObjects(1).QueryTable.Connection = "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & """" & ThisWorkbook.Queries.Item(QueryCount + 1).Name & """" & ";Extended Properties=" & """" & """"
ThisWorkbook.Sheets(3).ListObjects(1).QueryTable.CommandText = "SELECT * FROM [" & ThisWorkbook.Queries.Item(QueryCount + 1).Name & "]"
'Refresh the new connection
ThisWorkbook.Sheets(3).ListObjects(1).QueryTable.Refresh BackgroundQuery:=False
End Sub
The second to last bunch, the 3 modifying the connection are the important ones. This is on a German Excel tho, so you may need to change the "Abfrage - " bit to fit your language. It's just important that you correctly change the WorkbookConnection, Connection and CommantText correctly.

Related

how to use cells for a Hyperlink destination/path and workbook name VBA?

I have a folder on the desktop
C:\Users\ME\Desktop\folder1\folder2\
In workbook 1 have column A which was used to create folders within folder 2.
Column N was then used to create filenames for each newly created workbook.
Every Row became a new workbook. (~3200 Workbooks, each in their own folder)
How can I either write a VBA or a Formula to quickly create the hyperlinks.
The reasoning is that the Master workbook will be used to narrow down the the search results and give immediate access to that location of the database.
the path I have is,
C:\Users\ME\Desktop\folder1\folder2\ & Column A & "/" & Column N & ".xlsm"
I tried using a formula
=HYPERLINK('C':\Users\ME\Desktop\folder1\folder2\ & [#SITE] & "/" & [#FULLNAME] & ".xlsm",[#FULLNAME])
This doesn't seam to work, the Cells I'm referencing is stated as the column headers. When I hit enter the entire column downward was then filled with "#NAME?" and a error stating "the formula contains unrecognized text"
Flip "/" into a "\"
Also look at this example for guidance:
=HYPERLINK(C10&"\"&A10&"\"&B10&".xlsx")
Perhaps use formula like this in New column and use it for the whole range:
=HYPERLINK("C:\Users\ME\Desktop\folder1\folder2\ & $A2 & "/" & $N2 & ".xlsm","PathToFile_" & $N2)

Vlookup to a table on a different user selected file VBA Macro

I am trying to enter a Vlookup formula into Column S of a worksheet named "FY_16". I need the user to select the file (which changes each month) that the "table array" for the formula is in.
Each month the file changes, but the column I want to look up to will always be the same - Column W (but have varying number of rows). The "table array" that the formula will look up to is part of a table.
My code at this point is below:
Private Function UseFileDialogOpen()
MsgBox ("When the browse window opens: please select the previous months published FY16 Consulting SKU File")
Dim myString As String
' Open the file dialog
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Show
If .SelectedItems.Count = 1 Then
myString = .SelectedItems(1)
'MsgBox myString
UseFileDialogOpen = myString
Else
MsgBox ("Failed to properly open file")
myString = "fail"
UseFileDialogOpen = myString
End If
End With
End Function
Sub Vlookup
Dim filelocation 'as what?????
filelocation = UseFileDialogOpen()
Worksheets("FY_16").Range("T2:T" & LastRow).FormulaR1C1 = "=vlookup(RC[-3], [" & myString & "] PA Rev!R1C23:R900000C23,1,false)"
My issue occurs on the final line of code. I receive a "run time error 1004 : application defined or object defined" message.
I know my syntax is incorrect for the vlookup in a few ways. I am not sure the "& myString & " is correct, perhaps this should be "filelocation"?
I also don't believe R1C1 can be used to name a range like I have in the vlookup. I typically would use
.Range(Cells(2,23), Cells(90000,23))
But I am not sure how to use that with the variable that holds the selected file name.
Also, I am using the 90000 row because this will go past my data each month (usually row count is around 75000). I would much rather find the exact row number but I don't believe this can be done without opening the "target file" selected by the user. If there is a way to achieve this, please offer any advice!
I am wondering if there is a way to use the Table Names to set the table array?
The non-VBA vlookup is as follows:
=VLOOKUP(Q2,'TargetFile.xlsb'!REV[[#All],[Net New Match]],1,FALSE)
TargetFile is the user selected file
REV is the worksheet the table array is on
Net New Match is the column I want to look up to (the entire column)
I played around with using these table names but couldn't get the syntax correct (possibly because the rest of the formula code is incorrect also).
Any help will be greatly appreciated. Let me know if any clarification is needed.
Mike
The correct syntax for accessing a range in an unopened workbook would be something that looks like 'C:\Temp\[Book2.xlsx]PA Rev'!R1C23:R900000C23. That won't be the same format that comes from the UseFileDialogOpen function.
You also can't use myString within your Vlookup subroutine because you defined that variable to be local to UseFileDialogOpen - but you can use filelocation which you have used to store the result from UseFileDialogOpen. But, as I said, it won't be in the right format anyway, so it will require a bit of reformatting.
The following command should do the necessary reformatting:
Worksheets("FY_16").Range("T2:T" & LastRow).FormulaR1C1 = _
"=vlookup(RC[-3],'" & Left(fileLocation, InStrRev(fileLocation, "\")) & _
"[" & Mid(fileLocation, InStrRev(fileLocation, "\") + 1) & _
"]PA Rev'!R1C23:R90000C23,1,false)"

How to pull data into excel from access?

I have an excel worksheet that has two sheets. On the first one i have the printable page and the second sheet is for the first to pull data from using vlookup. The second sheet consists of 8 columns. The first column is the ID that's being used by vlookup on the first page. The second is for first/last name. What i want to do is to make excel search for this (first/last name) in an access database and then retrieve and fill 3 other columns from the data in access. There are 2 tables that i want it to look into. It will find the name in either one of them and there are no duplicates. Does anyone have any idea how i might achieve this? Thanks!
You have a few choices. One is to use an .ODC using "Data-Get External Data". If you go through the wizard you can store the search criteria in the external data link (and if desired save this as an .ODC file). If you record a Macro when doing this, you will see where you can alter the recorded VBA code to substitute your own criteria from Excel (e.g, First/Lame name).
Another way, if your data isn't too big is to bring in a single sheet with "Data-GetExternalData" containing all your data then use VLookup (or index/match) to just retrieve the appropriate names. This works well when your database is not too big to bring entirely into Excel, efficiently.
But I use the following code because it's slick and doesn't require exposing any connection info (including passwords) in the .ODC (stored external data link). It's also faster. In this example, I use ADO because it's a SQL/Server database, but if the data is in Access (.ACCDB or MDB) then you can use ordinary DAO. If you need the ADO, don't forget to include the ADO library in your references.
In my example, I used a date range to find the data I wanted. In your case, it would be Lname and Fname instead of a date range.
This Excel VBA code is what I use.
Sub RefreshReport()
On Error GoTo Err_Handler
verrevent = "RefreshReport"
Dim rs As New ADODB.Recordset
If cn.State = 0 Then OpenNewConnection
Dim xlRange As Excel.Range
'Delete prior data
Range("MyTargetTable").EntireRow.Delete
'Call sproc to fetch member match
'This uses SPROC, but could be any SQL statement passing search criteria from Excel
vsql = "sproc_my_procedure '" & Range("BegDate") & "' ,'" & Range("EndDate") & "'"
'Call sproc to fetch member match
Set xlRange = Range("MyTargetDataSheet!A2")
Set rs = cn.Execute(vsql)
xlRange.Cells.CopyFromRecordset rs
'Refresh a pivot table if you have one
Set pt = Sheets("Summary").PivotTables("PivotTable1")
pt.RefreshTable
MsgBox ("Refresh Complete")
Exit_Proc:
Exit Sub
Err_Handler:
MsgBox ("Refresh program error. Please snip and send." & vbCrLf & vbCrLf & "Err " & Err.Number & " " & verrevent & " " & vbCrLf & Err.Description & vbCrLf)
Resume Exit_Proc
End Sub

Calling an existing worksheet with vba by using its code name in excel

I am trying to set the formula of a cell to an if formula that uses data from an already existing sheet within the workbook. However whenever trying to reference the sheet i get a file dialog box that opens looking for the path for the sheet. Below you will find my code which loops through all existing sheets in the workbook and compares it to a sheet name when it finds a match it stores the sheet code name for the current and previous weeks. Once it has these I have an if statement that tries to access these sheets and compare values. It is at this point that I get the file dialog box. Any thoughts or suggestions would be greatly appreciated. Thank you. Sorry for formatting issues I will correct as soon as possible.
sheetName = CStr(Year(Now)) & " eDR FW" & CStr(Format(Date, "ww")) & "_2"
lastWeekName = CStr(Year(Now)) & " eDR FW" & CStr(Format(Date, "ww") - 1) & "_2"
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = sheetName Then
sheetName = ws.CodeName
ElseIf ws.Name = lastWeekName Then
lastWeekName = ws.CodeName
End If
Next
rowRange = colLetter & "2:" & colLetter & CStr(sheetRowCount)
lineofBalance = "=IFERROR(IF(INDEX('" & lastWeekName & "'!$A$2:$W$10000,MATCH(A2,'" & sheetName & "'!$A$2:$A$10000,0),6)=F2,F2,CONCATENATE(""Updated: ""&F2)),CONCATENATE(""New: ""&F2))"
All you need to do to make this work is change both ws.Codename to ws.Name.
The .Codename property only contains the first name of the sheet when it was originally created (which is most likely something like "Sheet32") and not the current name of the worksheet. It CAN be changed but most likely will remain the same unless you REALLY intend to change it. The formula with the erroneous worksheet name then opens the dialog box to try to find a reference for that particular worksheet.
Excel's formulas are designed to work with the current worksheet name and not it's codename. The only useful way I can see of using the .Codename, is if you wanna make sure to always use a particular worksheet (within VBA) even if the name of the worksheet was changed at some point (by yourself or a user).

Excel VBA inserting formula with variable that references a different sheet links to saved file rather than open file

I have this line in a long sub and as title mentions instead of using values from the open workbook it uses the saved file and every time it runs it requires manual linking to file.
MC is a workbook APs is a workbook name as a string cl is a range.
MC.Sheets("MasterC").Range("$Z$1").Value = "='[" & APs & " ]Stock'!" & cl.Offset(0, 11).Address
this is a line in a for loop where cl is a single cell in a range.So can't use absolute values. I've used .formulaR1C1instead of .value to no avail.
So figured out that it was a trivial thing
MC.Sheets("MasterC").Range("$Z$1").Value = "='[" & APs & "]Stock'!" & cl.Offset(0, 11).Address
In original line there was a space between " and the square bracket causing issues. Moral of story check for spaces.