Listing links in designated worksheet vba - vba

I amended the below so the links would go into a sheet of my choosing, but I get errors, I am keen to know is there a way of setting the ws of my choosing. I looked on the net and could not find a solution.
Sub ListLinks()
Dim wb As Workbook
Set wb = Application.ActiveWorkbook
If Not IsEmpty(wb.LinkSources(xlExcelLinks)) Then
wb.Sheets.Add ' Amended this with my chosen sheet I want the links to go and I get errors after, declaring my variables, i.e ws as worksheet and the range
xIndex = 1
For Each link In wb.LinkSources(xlExcelLinks)
Application.ActiveSheet.Cells(xIndex, 1).Value = link
xIndex = xIndex + 1
Next link
End If
End Sub
I have a workbook, that has several worksheets that have two external links to two different workbooks.
I am unable to use left or right function to extract the path filename from a VLOOKUP FORMULA of a cell to a cell of my choosing, let's take the example of one link, let's say that I wanted to print the formula as text into cell B1 and then say C1 would have the path of the most updated file that I would want to change it to. Using VBA to change the file. Once this has updated the link, both B1 and C1 should = the same file and path location.
If I could do this than I would try to see if I could apply it to the second link.
Is there a way of printing the formula of a cell as text and then using left, middle or right to extract path and file location.
I thought about the above vba code but it adds a new sheet, I am unable to put the links into the sheet of my choosing. I get an error. I would be keen to use as less code as possible. I am a newbie in VBA, thoughts, and help would be appreciated.

If you wish to write to an existing sheet then instead of adding a sheet, you just need to specify the sheet on the writing line. So first remove the line wb.Sheets.Add. Then modify the write line - change ActiveSheet to Sheets("your sheet name"). In this example I've specified an existing sheet named "sandwich":
Sub ListLinks()
Dim wb As Workbook
Set wb = Application.ActiveWorkbook
If Not IsEmpty(wb.LinkSources(xlExcelLinks)) Then
xIndex = 1
For Each link In wb.LinkSources(xlExcelLinks)
Application.Sheets("sandwich").Cells(xIndex, 1).Value = link
xIndex = xIndex + 1
Next link
End If
End Sub
Additional:
If you wish to get the path from the formula/link, without VBA you may be able to use a formula like this if you are using Excel 2013 or later (in this example, your link is in cell A1):
=SUBSTITUTE(SUBSTITUTE(MID(FORMULATEXT(A1),FIND("'",FORMULATEXT(A1),1)+1,(FIND("]",FORMULATEXT(A1),1)-FIND("'",FORMULATEXT(A1),1)-1)),"''","'"),"[","")

Related

VBA Macro: Designating Sheets() with vlaues in a worksheet

I am trying to do the following:
There is a group of files of the same layout, and I would like to extract a specific page of each file and compile them together in one file.
I have manually created the compilation workbook, with each sheet named after the corresponding data source workbook.
I have created a loop that opens all the files and copy the specific sheet ("Target sheet"), but I am not sure how to paste them correctly.
Here is what I have so far:
Dim rw As Integer, prop As String
rw = 5
Do While rw < 44
prop = wb1.Sheets("summary sheet").Cells(rw, 3).Value
Workbooks.Open Filename:= "(file address)", UpdateLinks:=False
Set wb2 = ActiveWorkbook
Set ws1 = wb2.Sheets("Target sheet")
ws1.Range("A1").Copy Range("BA150")
wb1.Sheets(prop).Cells(1, 1).Paste
wb2.Close SaveChanges:=False
rw = rw + 1
Loop
Note: the file address contains some sensitive info so I did not post it here, but it is coded as such that it can be looped.
Since the sheet names can be found in a certain location in the summary sheet in the compilation file, I tried to code the "Sheets()" with dynamic reference to that list, but I am getting error messages "Run-time error '438' Object doesn't support this property or method", with the wb1.Sheets(prop).Cells(1,1).Paste being highlighted as the faulty line. Can someone suggest a solution to this? Thank you very much in advance!
======EDIT======
I found a solution thanks to the two comments - for future reference:
ws1.Cells.Copy Destination:=wb1.Sheets(wsn).Range("A1")
I used numerical sheet reference instead. Probably needed to amend the original code to: (not tested)
ws1.Cells.Copy Destination:=wb1.Sheets(""" & prop & """).Range("A1")
To make it work.
If you are copying the entire sheet, then you can use
wb2.Sheets("Target Sheet").Copy After:=wb2
Rather than copy/paste.
It basically copies the entire sheet to the other workbook.

Worksheet.Select switching screens excel VBA

I currently have 3 sheets: Input, Process, Output and a macro that uses values displayed on the input sheet and various stores on the process sheet. The problem is when the user presses a submit button linked to the macro on the input page the sheet switches to the Process sheet before displaying the Output sheet. I understand that this is because of this line of code:
Worksheets("Process").Select
However whenever I remove it from the macro everything goes madly out of range. Is there any way of selecting a sheet without actually visually moving to it? I need the macro to do its thing and then simply display the output sheet. Thanks in advance!
As #Jeeped stated and referenced, avoid using Select and Activate, in addition it is safer to qualify references.
For example you can use Range("A1").Value to get a value of the cell A1 in the currently active worksheet, but what if the user didn't have that sheet active at the time or another proc had moved the view? you could get the value of cell A1 from potentially any worksheet.
It would be best to create a reference to the worksheet and then send all your work through it, this way you do not need to change the active worksheet and there is no ambiguity about where the range values are coming from.
For example: -
Option Explicit
Dim WkSht_I As Worksheet 'Input
Dim WkSht_P As Worksheet 'Process
Dim WkSht_O As Worksheet 'Output
Public Sub Sample()
Set WkSht_I = ThisWorkbook.Worksheets("Input")
Set WkSht_P = ThisWorkbook.Worksheets("Process")
Set WkSht_O = ThisWorkbook.Worksheets("Output")
MsgBox "Input A1 = " & WkSht_I.Range("A1").Value
MsgBox "Process A1 = " & WkSht_P.Range("A1").Value
MsgBox "Output A1 = " & WkSht_O.Range("A1").Value
Set WkSht_O = Nothing
Set WkSht_P = Nothing
Set WkSht_I = Nothing
End Sub
Converting your procedures to this method should be safer and clearer and you can set the active sheet just once for it to show content while the others or being worked on.
#Gary's method is the best method to go with when you are working with multiple worksheets.
If you are working with only two sheets, (Considering you have activesheet and target sheet) I am going to recommend
With Worksheets("Process")
Debug.Print .Range("A1")
Debug.Print Range("A1")
End With
Notice "." infront of Range.
The "." indicates that it is part of With
In other words, .Range("A1") is same as Worksheets("Process").Range("A1")
Because second Range("A1") does not have "." it is same as Activesheet.Range("B1") even it's inside of the With-End
If the activesheet is Process Then the out put will be same
But when you select worksheet other than Process, because activesheet changed, the output will be different.
This will avoide using Select which changes the activesheet

Sheets that have almost the same name

Im trying to open and copy the cells from a sheet from a different excel file. I have no problem in opening, copying and closing the excel file that I need.In this case, I have With x.Sheets("Documents").UsedRange. Most files that I needed to copy the cells from have "Documents" as a sheet name, but some have "Documents" + other different characters (example, "DocuemntsEX"). When I tried to copy, it shows 'Subscript Out-of-range' since the "DocumentEX" is different from "Document". Is there any way that I can retain the specific name of the sheet, since most of the files have that name? Is there any code that can help me to access those sheet with a different sheetname? Just hit me up if you need clarifications.
Use a wildcard character to get the sheet first:
Function GetDocumentSheet(ByRef wb As Workbook) As Worksheet
For Each ws In wb.Sheets
If LCase$(ws.Name) Like "documents*" Then
Set GetDocumentSheet = ws
GoTo SheetFound:
End If
Next
Set GetDocumentSheet = Nothing
SheetFound:
End Function
In your code:
Set mySheet = GetDocumentSheet(x) '// where 'x' is your workbook object
Then reference
mySheet.UsedRange
As i said in comment, you can use sheets by number, or you can use something like this
Sub findSheet()
Dim sheetSubName As String
sheetSubName = "fluff"
Dim currentSheet As Worksheet
For Each currentSheet In Sheets
If currentSheet.Name Like sheetSubName & "*" Then
MsgBox "do some stuff"
End If
Next currentSheet
End Sub
When you comparing sheet name to string and regular character (in my example * so its anything). So this macro will work with sheet fluff, fluffy fluffiest etc.
And everything to looping via Sheets (all sheet in workbook) and comparing their names via Like (something like = ) but it can use some basic regular expression.

Multi language Excel VBA Application

I basically created an Excel VBA application that manipulate Excel worksheets, so in the code, I use the string "Sheet1" to refer to the first sheet of a workbook, but when I try to use this application with the same code with a french version of Excel, it doesn't work until I translate "Sheet1" to "Feuil1". So my question is, is there a way to automatically adapt the code to any version of Excel ?
You can use the following ways to get a sheet from code:
(1) using by Sheets(sheet_index)
This way cannot be adapt because it take the sheet by sheet index (sheet index are start from 1). When sheet are change place, it cannot access the right sheet.So, it should not use.
For example: Set Feuil1Sheet = Sheets(1)
(2) using by (Name) of VBA editor
I think this way should not use never, because it takes the sheet by code name which can only visible by VBA editor(it shows as (Name) field in sheet properties). I think you are using this way for getting the first sheet. So, you not get the right sheet. One thing you need to know is that code name of every first sheet may not be Sheet1 always. It can be Sheet2 or Sheet4, etc.
For example: Set Feuil1Sheet = Sheet1
(3) using Worksheets("sheet-name") or Sheets("sheet-name")
This last way is a very compatible way and can be adapt in anywhere Excel because it take the sheet by its name. So, If names are equal, you will get the right sheet. So, use this for getting the sheet.
For example: Set Feuil1Sheet = Worksheets("Feuil1") or Set Feuil1Sheet = Sheets("Feuil1")
The only possible way I can think of to always reference "sheet1" in the local language is the following code.
Option Explicit
Public Sub GetLocalNameForNewSheets()
Dim strSheetName As String
Dim i As Long
i = ActiveWorkbook.Sheets.Count
ActiveWorkbook.Sheets.Add After:=Worksheets(i)
strSheetName = ActiveWorkbook.Worksheets(i + 1).Name
Application.DisplayAlerts = False
ActiveWorkbook.Worksheets(i + 1).Delete
Application.DisplayAlerts = True
Debug.Print strSheetName
For i = 1 To Len(strSheetName)
While IsNumeric(Mid(strSheetName, i, 1))
strSheetName = Replace(strSheetName, Mid(strSheetName, i, 1), "")
Wend
Next i
Debug.Print strSheetName
Debug.Print strSheetName & "1"
End Sub
Basically, I am asking Excel to create a new sheet and name it for me. Then, I am getting the new name which is "sheet" in the local language and remove from the string the number part. At the end, you can add the number "1" to reference the first sheet.

VB Compare two range of cells in multiple workbooks and if match copy to different cell

I am trying to figure this out all day. This is what I need to accomplish:
Using GetFile select a number of workbooks without opening them.
Compare Cell A2 of selected workbooks indiviually in loop to a reference workbook.
If Cell A2 of the selected workbook equals the numerical value of the numerical value within the reference workbook contained within column A then copy/past column B's text in the corresponding cell of the matched reference workbook cell to M2 of the selected workbook.
Sounds complicated but let me demonstrate. The letters represent column names.
Selected Workbook
A2=12 M2= ""
Reference Workbook
A2=12 B2=milk, protein
Desired result:
Selected Workbook
A2=12 M2=milk, protein
So far this is the code I have:
Sub Click()
Dim rCell As Range, vVal1, vVal2
Dim wbCheck As Workbook
For Each rCell In Workbooks("2.xls").Worksheets(1).Range("A1:C100")
vVal1 = rCell
vVal2 = ThisWorkbook.Worksheets(1).Range(rCell.Address)
If IsNumeric(vVal1) And IsNumeric(vVal1) Then
If vVal1 = vVal2 Then
rCell.Interior.ColorIndex = 3
ElseIf vVal1 < > vVal2 Then
End If
End If
Next rCell
End Sub
Why do you need a VBA code for this?
This can be achieved using an Excel Formula.
Paste this in M2 and copy it down
=IF(A2='C:\[Ref.xlsx]Sheet1'!A2,'C:\[Ref.xlsx]Sheet1'!B2,"")
My Assumptions (Please change as applicable)
The reference file name is Ref.xlsx
You are pulling data from Sheet1 of reference file
The Ref.xlsx is in C:
EDIT
Even if you want to use VBA, you can also do this.
Sub Sample()
Application.Calculation = xlCalculationManual
ThisWorkbook.Sheets("Sheet1").Range("M2").Formula = _
"=IF(A2='C:\[Sample.xlsx]Sheet1'!A2,'C:\[Sample.xlsx]Sheet1'!B2,"""")"
Application.Calculation = xlCalculationAutomatic
End Sub
The above formula or code is beneficial becuase of what you mentioned in 1st point Using GetFile select a number of workbooks without opening them. If you do not want to open the file then the formula or formula in VBA is the way to go :)
I solved my own question. The answer was to use VLookup.
=VLOOKUP(I2, 'C:\Desktop\Merge[ISReference.xlsx]Reference'!B2:G1923, 6, FALSE)
I am surprised no one suggested this to me. Given its simplicity I was able to build this function into some code I built to run through a FSO filedialog picker on a form in access and link external workbooks with Vlookup.
Thanks Siddarth for giving the proper direction of embedding a function instead of crazy iterated loop.