Excel VBA macro - Change link name - vba

I have a excel macro routine that I need to prep a file for another routine which is run daily. This prepping involves changes the links of t-1 file to a t0 file.
The code I usually do is:
ActiveWorkbook.ChangeLink Name:= _
"file path", NewName:=new_file_path, Type:=xlExcelLinks
My trouble now is that for this particular routine the file path to be changed to a new routine is not always the same, thus I would need a way to automatize finding out what are the current links to replace them all. The new file path I now because it is the worksheet that is calling this routine and opening this file, so first thing I do Is
new_file_path = "C:\...."& ActiveWorkbook.Name & ".xlsm"
What would help me is if there is a trick to replace all links for a new one, without the need to say the name/path of the old links. Does any one know?
Thanks

To change all the excel links in a workbook try this procedure:
Sub WbThs_ChangeLink_Excel()
Dim wbTrg As Workbook
Dim sLinkNew As String
Dim aLinks As Variant, vLink As Variant
sLinkNew = "##VBA Links Replace - Target 3.xlsb" 'Change as required
Set wbTrg = ThisWorkbook 'Change as required
Rem Set array with all excel links
aLinks = ActiveWorkbook.LinkSources(xlExcelLinks)
Rem Replace each excel Link
If Not IsEmpty(aLinks) Then
For Each vLink In aLinks
wbTrg.ChangeLink Name:=vLink, NewName:=sLinkNew, Type:=xlExcelLinks
Next: End If
End Sub
See the following pages for additional information on the resources used:
Workbook.ChangeLink Method (Excel)
Workbook.LinkSources Method (Excel)
XlLink Enumeration (Excel)

Related

How to open and activate another workbook in VBA?

I'm creating a macro where I will need to run it in 1 file (called "Masterfile"), it will open and execute the macro on another file ("SurveyReport") and then give me a message box saying "done!".
The code I have to execute on the SurveyReport file works fine when I open that file manually and execute it. The code I need to open SurveyReport from MasterFile is also working it seems, I ran the below with no issues:
Sub PivotTable()
'
' PivotTable Macro
Dim MasterFile As String
MasterFile = ActiveWorkbook.Name
Dim SurveyReport As String
SurveyReport = Application.GetOpenFilename("Excel files (*.xlsx), *xlsx", 1, "Please select the Survey Create Report file", , False)
Workbooks.Open (SurveyReport)
End Sub
But, when I try to activate the SurveyReport file so I can begin executing the macro in it, I get a "Subscript out of range" error. I've tried using the following code after the above block and before the code to execute in the SurveyReport file:
Windows(SurveyReport).Activate
This didn't work, not did:
ThisWorkbook.Activate
...which only had the effect of activating the MasterFile.
SurveyReport file is a .xlsx file. I tried saving it as a .xls file and amending the code, but no joy.
I also tried passing it the file name directly (i.e. Windows("filename.xlsx").Activate), same issue.
ActiveWorkbook is as it says on the tin - whichever workbook happens to be active when the code runs.
ThisWorkbook is always the workbook that the code is sitting in.
You can SET references to specific workbooks rather than just using their names each time. A name can change, or reference the wrong object.... imagine you have a friend called Darren. Each time you mention him you mention him by name. Someone that doesn't know Darren hasn't a clue which Darren out of all the ones available in the world you're talking about. Now imagine you have a little replica of Darren in your pocket... nah, that's a terrible anology - it wouldn't be a replica, it would be a reference to the real Darren... anyway, I digress.
This code sets a reference to the workbook, you can then use that reference any time you want to refer to the correct workbook:
Sub PivotTable()
Dim MasterFile As Workbook
Dim SurveyRptName As String
Dim SurveyReport As Workbook
Set MasterFile = ThisWorkbook '
SurveyRptName = Application.GetOpenFilename("Excel files (*.xlsx), *xlsx", 1, _
"Please select the Survey Create Report file", , False)
If SurveyRptName <> "False" Then
Set SurveyReport = Workbooks.Open(SurveyRptName)
End If
SurveyReport.Activate 'You don't need this line. It doesn't matter if
'the workbook is active, the code knows which one
'you're talking about in the next line.
MsgBox "This is " & SurveyReport.Name & _
" containing " & SurveyReport.Worksheets.Count & " sheets." & vbCr & _
"The value in cell A1 of the first sheet is " & _
SurveyReport.Worksheets(1).Range("A1")
End Sub
Edit: Of course, if you press Cancel when selecting a file then the lines following the IF...THEN code won't have a reference to work on and you'll get a Object Variable or With block variable not set - best not to run the bottom bit of code if you haven't successfully opened the Survey Report file.
The part of the answer that is missing - is that he tried to call a method of an object when his variable was STRING - the open command and subsequent commands will give you an OBJECT - which has properties and methods like .Activate. The STRING type has no such method or property (to be sure - it may have others).
the solution provided by Darren solves this by declaring his SurveyReport as type Workbook - an object of Excel.

getting vales from different file locations contained in cells Excel

So I'm trying to create a tracking file in Excel and in cell M5, I have a file location which links to a supporting document and as such, contains some duplicated information so I want to try and pull certain fields (B8 in this example) from the external files referenced in M5.
I have tried =([M5]Sheet1!B8) which works to a degree but this brings up a dialogue box and I have to select the file location manually which is too manual for the purpose.
I have also looked into using the INDIRECT function but can't guarantee that both files will be open at the same time, so would prefer another option if possible.
Any suggestions would be hugely appreciated!!
Here is formula you can use to get individual cell values from a closed workbook.
It is a User Defined Function (UDF) and you call it like this:
=GetClosedCell(A3,B3,C3)
The 1st parameter is the workbook path and name.
The 2nd parameter is the worksheet name.
The 3rd parameter is the address of the cell.
Place this function in a standard code module:
Public Function GetClosedCell(ByVal FileSpec$, ByVal SheetName$, ByVal RangeAddress$)
Const CNX = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=[];Extended Properties=""Excel 12.0;imex=1;hdr=no;"""
Const QRY = "SELECT * FROM [.$|:|]"
On Error GoTo errorh
RangeAddress = Range(RangeAddress)(1, 1).Address(0, 0)
With CreateObject("adodb.recordset")
.Open Replace(Replace(QRY, "|", RangeAddress), ".", SheetName), Replace(CNX, "[]", FileSpec)
GetClosedCell = .Fields(0)
End With
Exit Function
errorh:
GetClosedCell = "ERROR: " & Err & " " & Err.Description
End Function
Here is how it would look on a worksheet:
It is possible to grab data from an external file without opening it. For Excel to get a data item, it needs to know:
the file location
the name of the file within that location
the name of the worksheet within that file
the address of the cell within that worksheet
We enter the required info into some cell, say cell C3 in a very specific format:
'C:\TestFolder\[ABC.xls]xxx'!R9C2
note the single quotes!
then running this short macro:
Public Sub GrabData()
Dim r1 As Range, r2 As Range
Set r1 = Range("C3")
Set r2 = Range("C4")
r2.Value = ExecuteExcel4Macro(r1.Value)
End Sub
will retrieve the data and place it in cell C4
Macros are very easy to install and use:
ALT-F11 brings up the VBE window
ALT-I
ALT-M opens a fresh module
paste the stuff in and close the VBE window
If you save the workbook, the macro will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the macro:
bring up the VBE window as above
clear the code out
close the VBE window
To use the macro from Excel:
ALT-F8
Select the macro
Touch RUN
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
Macros must be enabled for this to work!

Calling a function from another Excel workbook

I've got a pile of data in one worksheet that I am trying to save to individual workbooks based on values in several columns. The approach I am taking (for better or worse!) is to copy the relevant worksheet (and macros) to a new workbook, save it with an appropriate name (let's say temp.xlsx), and then to cleanse the data in that new workbook by deleting irrelevant rows (function called deleteInfo). This all has to be done without altering the original workbook, as per company policy.
I can copy the stuff over no problem, but I'm having serious issues calling macros in the new workbook then.
I have tried:
Application.Run "'temp.xlsx'!deleteInfo"
ActiveWorkbook.Application.Run deleteInfo
Application.Run ("'C:\user\.....\temp.xlsx'!deleteInfo")
But none have worked.
For the task like this you should consider creating an Excel add-in (file extension .xla) containing VBA macros while keeping the regular Workbooks with data macro-free (extension .xls or .xlsx). More details in Microsoft online article: https://support.office.com/en-ca/article/Add-or-remove-add-ins-0af570c4-5cf3-4fa9-9b88-403625a0b460
Hope this may help.
Solved this issue by exporting the module in which the macro was saved, copying the original workbook and importing it into the new workbook. pathName was defined in previous module to this as the path to the original file's folder (pathName = ActiveWorkbook.Path)
Sub exportMacro(ByVal pathName As String)
'Export the macro to save as .bas file
On Error Resume Next
Kill pathName & "\Module6.bas" 'Delete previously exported file
On Error GoTo 0
ActiveWorkbook.VBProject.VBComponents("Module6").Export pathName & "\Module6.bas"
End Sub
Sub importMacro(ByVal pathName As String)
'import the macro to a new workbook
ActiveWorkbook.VBProject.VBComponents.Import pathName & "\Module6.bas"
End Sub

How to find location of link in Excel workbook?

I have an Excel book that, when opened, gives the warning:
This workbook contains links to other data sources.
I want to remove all of these links so that the warning will not be triggered. Thinking that any external link will be of the form '[workbook path]'!address I used this code:
Sub ListLinks()
Dim wb As Workbook
Dim link As Variant
Set wb = ThisWorkbook
For Each link In wb.LinkSources(xlExcelLinks)
Debug.Print link
Next link
End Sub
This returned a file path:
\\somePath\xyz\aWorkbook.xlsm
I searched all formulas in the workbook for this string using Ctrl+F, but no results were returned. How do I find and remove this link?
Your workbook could be linking via a named range pointing to another workbook. A search of formulas for the linked workbook may find nothing because the link is hidden in the name.
Check your named ranges for links to other workbooks.
Breaking the links is not enough to suppress the warning. On the Edit Links window, I clicked Startup Prompt and set the radio button to "Don't display the alert and don't update automatic links". This successfully prevented the warning from appearing.
The following loop should work.
Dim intCounter As Integer
Dim varLink As Variant
'Define variable as an Excel link type.
varLink = ActiveWorkbook.LinkSources(Type:=xlLinkTypeExcelLinks)
'Are there any links?
If IsArray(varLink) = False Then
Exit Sub
End If
'Break the links in the active workbook.
For intCounter = 1 To UBound(varLink)
ActiveWorkbook.BreakLink _
Name:=varLink(intCounter), _
Type:=xlLinkTypeExcelLinks
Next intCounter
I had this problem after removing all the links as described above, I then found that some of my validation data was refering to other workbooks. After correcting this the problem disappeared.
Could be in one of these?:
HYPERLINKS (formula and normal)
NAME MANAGER
VALIDATION
CONDITIONAL FORMATTING
BUTTON WITH MACRO (still pointing to originating macro)

VBA - Copy as Path

I need help with a coding requirement that I've not previously experienced. I just browsed a similar issue raised here a couple of years ago - VBA to Copy files using complete path and file names listed in Excel Object.
My issue is similar but somewhat simpler than the OP.
I have a number of folders that each contain about 100 small .csv files; for each folder I need to copy the path for each file to an open worksheet. Each folder of .csv files has its own associated workbook.
As one example, the open workbook is F:\SM\M400AD.xlsm and the active worksheet is CSV_List. The folder containing the .csv files is F:\SM\M400AD.
Doing it manually, my sequence is then:
Open folder F:\SM\M400AD
Select all
Copy path
Paste to Range("B11") of worksheet CSV_List
When I do it manually, as described above, I get a list that looks like:
"F:\SM\M400AD\AC1.csv"
"F:\SM\M400AD\AC2.csv"
"F:\SM\M400AD\AE.csv"
"F:\SM\M400AD\AF.csv"
"F:\SM\M400AD\AG.csv"
"F:\SM\M400AD\AH1.csv"
"F:\SM\M400AD\AH2.csv"
"F:\SM\M400AD\AJ.csv"
and on down the page until I have a list of 100 paths. This single column list is then pasted into worksheet CSV_List, starting at Range("B11").
I need to automate this and would be grateful if a VBA guru could kindly code this for me.
Such of question has been asked before, for example:
Loop through files in a folder using VBA?
List files in folder and subfolder with path to .txt file
The difference is you want to "automate" it, which means you want to execute code on workbook Open event.
How to achieve that?
Open F:\SM\M400AD.xlsm file.
Go to Code pane (ALT+F11)
Insert new module and copy below code
Option Explicit
Sub EnumCsVFilesInCurrentFolder()
Dim sPath As String, sFileName As String
Dim i As Integer
sPath = ThisWorkbook.Path & "\"
i = 11
Do
If Len(sFileName) = 0 Then GoTo SkipNext
If LCase(Right(sFileName, 4)) = ".csv" Then
'replcae 1 with proper sheet name!
ThisWorkbook.Worksheets(1).Range("B" & i) = sPath & sFileName
i = i + 1
End If
SkipNext:
sFileName = Dir(sPath)
Loop While sFileName <> ""
End Sub
Now, go to ThisWorkbook module and insert below procedure:
Private Sub Workbook_Open()
EnumCsVFilesInCurrentFolder
End Sub
Save and close workbook
The workbook is ready to use. Whenever you open it, EnumCsVFilesInCurrentFolder macro will be executed.
Note: you have to change above code to restrict the number of records.