Update four links in a workbook - vba

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

Related

In VBA trying to create a dynamic Sumifs Formula with multiple criterias in multiple sheets

In VBA I am trying to create a sumifs formula with multiple criteria across different workbooks, but I am struggling on the syntax.
WorkbookRecut.Worksheets("Summary").Activate
Dim CountRows As Long
Dim CountRows2 As Long
CountRows = WorkbookRecut.Worksheets("Summary").Range("I" & WorkbookRecut.Worksheets("Summary").Rows.Count - 1).End(xlUp).Row
CountRows2 = CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Range("I" & CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Rows.Count - 1).End(xlUp).Row
CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Activate
Range("O6").Formula = _
"=Sumifs(" & [WorkbookRecut].Sheets("Summary").Range("I9").Address & ":" & [WorkbookRecut].Sheets("Summary").Range("I" & CountRows).Address _
& "," & [WorkbookRecut].Sheets("Summary").Range("A9").Address & ":" & [WorkbookRecut].Sheets("Summary").Range("A" & CountRows).Address _
& "," & [CashBreaksMetricsWorkbookFinal].Worksheets("CSCIG_Cash Breaks Metrics").Range("K6").Address(Rowabsolute:=False) _
& "," & [WorkbookRecut].Sheets("Summary").Range("D9").Address & ":" & [WorkbookRecut].Sheets("Summary").Range("D" & CountRows).Address _
& "," & [CashBreaksMetricsWorkbookFinal].Worksheets("CSCIG_Cash Breaks Metrics").Range("N6").Address(Rowabsolute:=False) & ")"
CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Range("O6:O" & CountRows2).FillDown
Update
I have updated the most recent code. The only pending issue is the workbooks aren't changing, but all else works as I want :)
When creating a formula string to add to a cell you need to take into account where the different ranges are relative to the sheet where you're going to place the formula. Just calling Address() on one of the inputs may not give you what you want.
You can try something like the code below to abstract that part into a separate function:
Sub Tester()
Dim wsSumm As Worksheet, wsCBM As Worksheet
Dim lr As Long, f
Set wsSumm = WorkbookRecut.Worksheets("Summary")
Set wsCBM = CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics")
lr = wsSumm.Cells(Rows.Count, "I").End(xlUp).Row
f = "=SUMIFS(" & RealAddress(wsCBM, wsSumm.Range("I9:I" & lr)) & "," & _
RealAddress(wsCBM, wsSumm.Range("A9:A" & lr)) & ",$K6," & _
RealAddress(wsCBM, wsSumm.Range("D9:D" & lr)) & ",$N6)"
With wsCBM.Range("O9")
.Formula = f
End With
End Sub
'get a range address for `rngRef`,
' suitable for use in a formula on worksheet `ws`
Function RealAddress(ws, rngRef As Range) As String
Dim s As String
If ws.Parent Is rngRef.Worksheet.Parent Then 'same workbooks?
If Not ws Is rngRef.Worksheet Then s = "'" & rngRef.Worksheet.Name & "'!" 'diff. worksheets?
s = s & rngRef.Address(True, True)
Else
s = rngRef.Address(True, True, external:=True) 'different workbooks
End If
RealAddress = s
End Function
For the formula: You're probably looking for the .Address property from each of your Ranges. Something like Range1.Address & ":" & Range2.Address To get an output like $I$9:$I$307.
But for your Ranges, you need to put the CountRows inside the Range input like WorkbookRecut.Sheets("Summary").Range("A" & CountRows) and then add the .Address to it.
I also agree with #TimWilliams that your formula code could benefit greatly in terms of readability by adding some nicknames for your worksheets.
Here is what your code would look like with those 3 things corrected:
Public CashBreaksMetricsWorkbookFinal As Workbook
Public WorkbookRecut As Workbook
Dim SumSh As Worksheet
Set SumSh = WorkbookRecut.Sheets("Summary")
Dim CountRows As Long
CountRows = SumSh.Range("I" & SumSh.Rows.Count - 1).End(xlUp).Row
Dim CSCIG As Worksheet
Set CSCIG = CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics")
CSCIG.Activate
Range("O9").Formula = _
"=Sumifs(" & SumSh.Range("I9") & ":" & SumSh.Range("I" & CountRows).Address _
& "," & SumSh.Range("A9").Address & ":" & SumSh.Range("A" & CountRows).Address _
& "," & CSCIG.Range("K6").Address _
& "," & SumSh.Range("D9").Address & ":" & SumSh.Range("D" & CountRows).Address _
& "," & CSCIG.Range("N6").Address & ")"
CSCIG.Range("O9").FillDown
We were missing .Address(External:=True)
Thanks all for helping me get there (Finally!)
Final Code Below
Public CashBreaksMetricsWorkbookFinal As Workbook
Public WorkbookRecut As Workbook
Dim CountRows As Long
Dim CountRows2 As Long
CountRows = WorkbookRecut.Worksheets("Summary").Range("I" & WorkbookRecut.Worksheets("Summary").Rows.Count - 1).End(xlUp).Row
CountRows2 = CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Range("I" & CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Rows.Count - 1).End(xlUp).Row
CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Activate
Range("O6").Formula = _
"=Sumifs(" & [WorkbookRecut].Sheets("Summary").Range("I9").Address(External:=True) & ":" & [WorkbookRecut].Sheets("Summary").Range("I" & CountRows).Address(External:=True) _
& "," & [WorkbookRecut].Sheets("Summary").Range("A9").Address(External:=True) & ":" & [WorkbookRecut].Sheets("Summary").Range("A" & CountRows).Address(External:=True) _
& "," & [CashBreaksMetricsWorkbookFinal].Worksheets("CSCIG_Cash Breaks Metrics").Range("K6").Address(Rowabsolute:=False) _
& "," & [WorkbookRecut].Sheets("Summary").Range("D9").Address(External:=True) & ":" & [WorkbookRecut].Sheets("Summary").Range("D" & CountRows).Address(External:=True) _
& "," & [CashBreaksMetricsWorkbookFinal].Worksheets("CSCIG_Cash Breaks Metrics").Range("N6").Address(Rowabsolute:=False) & ")"
CashBreaksMetricsWorkbookFinal.Worksheets("CSCIG_Cash Breaks Metrics").Range("O6:O" & CountRows2).FillDown
In the formula, you have to double-quote existing quotes:
Change
Sheets("Summary")
to:
Sheets(""Summary"")

VBA code to combine powerquery tables into one new table

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

Save a single worksheet as CSV/xlsx file error 1004 (but does work when use 'export as fixed format' for PDF)

I have managed to get this to save as a PDF using 'ExportAsFixedFormat', but when I try to use 'SaveAs' to get a CSV (although I would accept xlsx too!) I get:
Run time error: 1004 Application defined or Object defined error
I have spent way to long trying to do this and can't find any answers that work for me online...
Sub SaveTrackingSheet()
Dim NewPathTrack As String
NewPathTrack = Application.ThisWorkbook.Path & "\PDF Outputs\" & Range("NameTrack").Text & "\"
If Dir(NewPathTrack, 63) = "" Then MkDir NewPathTrack
Dim NewPathDealer As String
NewPathDealer = NewPathTrack & Range("CodeTrack").Text & " - " & Range("NameTrack").Text & "\"
If Dir(NewPathDealer, 63) = "" Then MkDir NewPathDealer
Sheets("Tracking Sheet").SaveAs _
Filename:=NewPathDealer & "\" & Range("CodeTrack").Text & " - Tracking Sheet" & ".csv", _
FileFormat:=xlCSV, _
ConflictResolution:=2, _
Local:=True, _
CreateBackup:=False
End Sub
This is the line that errors:
Sheets("Tracking Sheet").SaveAs _
Filename:=NewPathDealer & "\" & Range("DealerCodeTrack").Text & " - Tracking Sheet" & ".csv", _
FileFormat:=xlCSV, _
ConflictResolution:=2, _
Local:=True, _
CreateBackup:=False
Thanks in advance!
fileformat:=xlCSVMSDOS
Check fileformat specifications at https://msdn.microsoft.com/es-es/vba/excel-vba/articles/xlfileformat-enumeration-excel
UPDATED RIGHT NOW:
The code that works for me is:
Sub SaveTrackingSheet()
Dim NewPathTrack As String
NewPathTrack = Application.ThisWorkbook.Path & "\PDF Outputs\" & Range("NameTrack").Text & "\"
If Dir(NewPathTrack, 63) = "" Then MkDir NewPathTrack
Dim NewPathDealer As String
NewPathDealer = NewPathTrack & Range("CodeTrack").Text & " - " & Range("NameTrack").Text & "\"
If Dir(NewPathDealer, 63) = "" Then MkDir NewPathDealer
Sheets("Tracking Sheet").SaveAs _
Filename:=NewPathDealer & Range("CodeTrack").Text & " - Tracking Sheet" & ".csv", _
FileFormat:=xlCSV, _
Local:=True, _
CreateBackup:=False
'ConflictResolution:=2 This line causes the error
End Sub
Hope it helps!

VBA Error Message: Object Variable or With Block Variable not Set. Can't See It

Line 22 is throwing the error (Set wbPath2)
This code is supposed to loop through each worksheet in my workbook and, as it loops, open another workbook related to the current loop iteration, then sum a column, then put that SUM in my original workbook. I'm getting and object error 91. I've been scratching my head for a while. Anyone know why this error message appears?
Private Sub PopulateData_Click()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim lastDay As Long
lastDay = Day(WorksheetFunction.EoMonth(ComboBox1.Value & Year(Date), 0))
monthNumber = Month(DateValue("01-" & ComboBox1.Value & "-1900"))
Root = "C:\myDirectory\" & Year(Date) & "\" &
monthNumber & ". " & ComboBox1.Value & " " & Year(Date) & "\"
'TOTAL CARS PER WEEK
Dim wbPath2 As Object
sourceFile = monthNumber & ". " & ComboBox1.Value & " " & Year(Date)
sourceSheet = "\[" & ws.Name & " " & monthNumber & "." & lastDay & "." &
Format(Now(), "yy") & ".csv]"
For Each ws In ThisWorkbook.Sheets
If (ws.Name <> "Master") And (ws.Name <> "Combined") Then
Set wbPath2 = Workbooks.Open(Root & ws.Name & " " & monthNumber &
"." & lastDay & "." & Format(Now(), "yy") & ".csv")
With ws
.Cells(Application.WorksheetFunction.Match("Total cars per
week", Range("A:A"), 0), 18).Formula = "=SUM('" & Root &
sourceFile & sourceSheet & ws.Name & " " & monthNumber & "." &
lastDay & "." & Format(Now(), "yy") & "'!$H:$H)"
End With
wbPath2.Close
MsgBox wbPath2
End If
Next
Application.ScreenUpdating = True
End Sub
I had to Set the ws object to resolve run time 91 error. Look in the comments section for Mat's Mug's additional bug fixes.
Private Sub PopulateData_Click()
Application.ScreenUpdating = False
Dim ws As Worksheet
Set ws = ThisWorkbook.Activesheet
'...

VBA FormulaR1C1 syntax with variable

i'm trying to write formula with 2 variables to cell.
formula in cell should be:
=(SUM('C:\Users\[Excel.xlsm]Sheet1'!H:H)-SUM('C:\Users\[Sheet1.xlsm]Sheet1'!I:I))
i want use path to file as variable, as well sheet name.
path = C:\Users\Excel.xlsm 'from msofiledialog
sheetname = Sheet1
what am i missing ?
Cells(1, 1).FormulaR1C1 = "=(SUM('[" & Path & "] " & sheetname & " '!C8) _
-SUM('[" & Path & "] " & sheetname & " '!C9))
thanks, this worked for me :
Sub main
Dim LastRow as String
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
Dim path as String
Path = "C:\users\username\Desktop\"
Dim filename as String
Filename = "Excel.xlsm"
Dim sheetname as String
sheetnameCR = "CR_" & supname
Dim myrangeH as String
Dim myrangeI as String
myrangeH = ("H5:H" & LastRow)
myrangeI = ("I5:I" & LastRow)
Cells(1, 1).Formula = "=SUM('" & Path & "[" & Filename & "]" & sheetnameCR & "'!" & myrangeH & ")" & "-SUM('" & Path & "[" & Filename & "]" & sheetnameCR & "'!" & myrangeI & ")"
End Sub
i had to add "RangeH" variable, because otherwise excel took cell C8, instead of column H, which i wanted.
that's great, but even after i give him full path to desired cell, excel is still asking me for path to excel with FileDialogOpen. any idea why ?