Formula referencing from other workbooks - excel

I'm quite new to VBA and I'm having trouble debugging a certain code. What I want is a cell formula that has the formula link to another spreadsheet. However, I want to add cells from multiple workbooks. For example, if we had workbook1 and workbook 2. I want in cell F10 in final workbook to have formula reading '[workbook1]Sheet1'!!F10' + '[workbook2]Sheet1'!!F10'
I like to make the formula as flexible and have the following conditions
I like to have an open directory that lets me select excel files that I want as part of the formula
I can add as many external spreadsheets as possible
The final spreadsheet initially will have zeroes in them. I want to replace this with a formula link.
How i decided to code this is by first replacing the zero cell of the final workbook with cell F10 of first excel file selected from a directory. Once this step is done, any additional workbooks selected from directory will add on as an extra formula link to the cell. Below is a code I attempted but I can not figure why it doesn't work. Could anyone please let me know what is going wrong? Thanks.
Sub Sum_workbooks_Form()
Dim FileNameXls, f
Dim wb As Workbook, i As Integer
FileNameXls = Application.GetOpenFilename(filefilter:="Excel Files, *.xl*", MultiSelect:=True)
If Not IsArray(FileNameXls) Then Exit Sub
For Each f In FileNameXls
Set wb = Workbooks.Open(f)
If ThisWorkbook.Sheets("Sheet1").Cells(11, 6).Value = 0 Then
ThisWorkbook.Sheets("Sheet1").Cells(11, 6).Formula = "=[" & wb.Name & "]Sheet1!" & Cell(11, 6).Name
Else
ThisWorkbook.Sheets("Sheet1").Cells(11, 6).Formula = "=[" & ThisWorkbook.Name & "]Sheet1!" & Cell(11, 6).Name & " + [" & wb.Name & "]Sheet1!" & Cell(11, 6).Name
End If
wb.Close SaveChanges:=False
Next f
End Sub

Well, normally a reference to cell F10 of Sheet1 of Book2 is expressed like this in a formula:
=[Book2]Sheet1!$F$10
Is it possible for you to reference the Sheet NAME instead of the NUMBER?
If yes, the first of your assignments should look like this:
ThisWorkbook.Sheets(9).Cells(11, 6).Formula = "=[" & wb.Name & "]Sheet1!$F$10"
Where Sheet1 is of course the name of your Sheets(9)

Related

Loop through folder and Copy values and Formats of first sheet

I have been working through VBA code that copies the first worksheet in a folder to another workbook.
The code copies the data correctly but upon saving I get certain cells with errors (#Ref) this is due some of the copied cells having formula.
I would like the copied to data to retain the original formatting but to only have values. Or alternatively the cells with the 2 errors are M11 and O11 which have an index match formula, if these 2 cells values could be pasted without formula the rest of the copied data will be fine.
Any help will be appreciated.
I have tried to use PasteSpecial xlPasteValuesAndNumberFormats and .PasteSpecial xlPasteFormats but I am not sure how to amend the copy function.
Sub MergeMultipleWorkbooks()
Dim Path, Filename As String
Path = "C:\Users\User\Desktop\ProMacro\"
Filename = Dir(Path & "*.xlsx")
Do While Filename <> ""
With Workbooks.Open(Filename:=Path & Filename, ReadOnly:=True)
.Worksheets(1).Copy After:=ThisWorkbook.Sheets(1)
.Close False
End With
Filename = Dir()
Loop
MsgBox "Files has been copied Successfull", , "MergeMultipleExcelFiles"
End Sub
The code copies the first sheet from the designated file in the folder, my only issue is that certain cells will have a #Ref when saving the file as the formulas having being copied.
When the workbook is opened, copy all the contents of the sheet and paste it to the same sheet as values. It's the code you put between
With Workbooks.Open(Filename:=Path & Filename, ReadOnly:=True) and .Worksheets(1).Copy After:=ThisWorkbook.Sheets(1)
Formatting is not changed and formulas are replaced by values.
It's not a very friendly solution, but nothing other comes to my mind after contemplating and trying to find out a good one.

How do I create a link in Excel, with a formula in it, to another Workbook?

I'm not sure if this is even possible in Excel but this is what I need to do:
I have a column with a list of hotels and then another column which needs to pull data from each individual hotel's excel file. For example, cell A2 will have the name "Paris" for the hotel and then cell B2 will have the link:
='G:\Hotels\Paris\Paris - Monthly\[Paris_summary_2018.xlsm]Feb'!$CD$89
I have lots of hotels I need to do this for in different sheets. So I need the link to dynamically refer to whatever hotel is in column A and the title of the sheet, for example could I do something like this?
=''G:\Hotels\A2\A2 - Monthly\[A2_summary_2018.xlsm]Feb'!$CD$89
where A2 has the string "Paris". Also is there a way to dynamically refer to "Feb" depending on what sheet I am in the month will be the title
I am also open to using VBA for this.
As long as you don't mind using VBA, you can easily generate the links with something like this:
Sub generate_hotel_links()
Dim r As Range, c As Range
Dim s As String
' This is the range which all the hotel-locations are in
Set r = ThisWorkbook.Worksheets("Sheet1").Range("A1:A10")
On Error Resume Next
For Each c In r
' Generate the formula based on the current cell we are in
s = "=" & Chr(39) & "G:\Hotels\" & CStr(c) & "\" & CStr(c) & " - Monthly\[" & CStr(c) & "_summary_2018.xlsm]Feb" & Chr(39) & "!$CD$89"
' ...and put it in the neighbouring cell
c.Offset(0, 1).Formula = s
Next c
On Error Goto 0
End Sub
On Error Resume Next will make the macro continue no matter what error pops up - the ideal case would be some more robust error handling, or a check for if the workbook / sheet actually exists before attempting to write the formula, but I'll leave it to you to attempt to write this if you feel the need improve the macro.
If you want to just use generic Excel formulas, I'd advice having a look at the question and answers I posted in the comments to your question.
I am not sure if you can use HYPERLINK.
Like this:
=HYPERLINK("G:\Hotels\"&A2&"\"&A2&" - Monthly\["&A2&"_summary_2018.xlsm]Feb!"&$CD$89)

convert Arabic saved Excel file to English

I have received the attached Excel file from my friend who wishes to convert into English(US).
While there is no Arabic text but only numerals, I am not able to work. If I copy and paste the cells into a new workbook, even the formats are saved. The numbers have spaces in between and I tried using Trim function.
Even if the spaces are deleted manually, the number is still shown on the right side of the formula bar. Pls help.
There are two settings regarding text direction and column layout within File, Option.
file, options, advanced, display, default direction.
... and,
file, options, advanced, display options for this worksheet, show sheet right to left
One way is to print to PDF, then open the PDF and export as spreadsheet. It's not perfect but I haven't found any of the other ways to reverse this.
This (https://www.extendoffice.com/documents/excel/1763-excel-change-sheet-direction.html) seemed helpful and may work for others but did not work for me, nothing did - the workbook that I had may have somehow been locked in this regard (I'm not sure if that's a thing but nothing I tried was correcting it)
Another possible solution is to open a new workbook with the correct structure and run a VBA script that copies, one sheet at a time and one cell at a time, from the Arabic-orientated workbook to the Western orientation. If there are graphs it will get a bit more tricky with putting them in the correct place but I'm sure for each sheet you could loop through each object, copy it and paste it in the other workbook and then move them around once there. Again not an easy or ideal solution, but a solution.
Here is a very simple implementation I'm using. It could be written in a more sophisticated way with objects, etc but this gets the job done. To use this, close all workbooks. Open the workbook you want to copy from. This is workbooks(1). Then open a new, blank workbook. Alt + F11 to bring up the VBA editor, add a module to your project and paste the code below.
Run step01, this creates the sheets in your new workbook.
In the new workbook, delete all default sheets - Sheet1, Sheet2 and Sheet 3.
Run step02. It can take some time as it's a slow method activating different workbooks. This will loop through every sheet, find the last cell and then loop through every cell. It will copy it, and paste it in the correct row order but in reverse column order in the new workbook.
Sub step01_create_sheets()
'create sheets in other workbook
Workbooks(1).Activate
For k = 1 To Workbooks(1).Sheets.Count
Workbooks(1).Activate
Workbooks(1).Sheets(k).Activate
val1 = Workbooks(1).ActiveSheet.Name
Workbooks(2).Activate
Workbooks(2).Sheets.Add(, Sheets(Sheets.Count)).Name = val1
Next k
End Sub
Sub step02_copy_sheet1()
Workbooks(1).Activate
Sheets(1).Activate
sheet_count = Workbooks(1).Sheets.Count
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
For m = 1 To sheet_count
Workbooks(1).Activate
Sheets(m).Activate
row_count = Range("a1").SpecialCells(xlCellTypeLastCell).Row
col_count = Range("a1").SpecialCells(xlCellTypeLastCell).Column
For k = 1 To row_count
For j = 1 To col_count
Workbooks(1).Activate
Sheets(m).Activate
val2 = Cells(k, j).Formula
Workbooks(2).Activate
Sheets(m).Activate
Cells(k, col_count - j + 1 + 1).Formula = val2
DoEvents
Application.StatusBar = "Sheet " & m & " of " & sheet_count & " ; Row " & k & " of " & row_count & "; Column " & j & " of " & col_count
Next j
Next k
Next m
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub

Externally Referencing Data with Variable Sheet Names

I am trying to import a range of cells from a closed workbook.
I use the external reference link built into Excel:
='F:\UGR\JOB DATA SHEET\[JOB SHEETS 1-500.xlsx]JobNumber'!B4
='F:\UGR\JOB DATA SHEET\[JOB SHEETS 1-500.xlsx]JobNumber'!B5
...
Going down the column from B4:B23 and replicating that for columns B-Z.
This works if the sheet name doesn't change. But that file contains sheets for Jobs 1 - 500, each on their own sheet. I am trying to pull those columns of data for whatever JobNumber gets entered into cell "B7". So ideally it would look like this:
='F:\UGR\JOB DATA SHEET\[JOB SHEETS 1-500.xlsx]&B7&'!B4
='F:\UGR\JOB DATA SHEET\[JOB SHEETS 1-500.xlsx]&B7&'!B5
...
Etc.
I know this won't work without the Indirect function, but I need to have the other file open for that to work. This isn't practical given the number of users who are using this file for reference.
I found a macro in VBA that should do what I need, but I can't get it to work. Here is the base macro before I started messing around with it.
Function GetValue(Path, File, Sheet, Ref)
'Retrieves a value from a closed workbook
Dim Arg As String
'Make sure the file exists
If Right(Path, 1) <> "\" Then Path = Path & "\"
If Dir(Path & File) = "" Then
GetValue = "File not Found"
Exit Function
End If
'Create the argument
Arg = "'" & Path & "[" & File & "]" & Sheet & "'!" & Range(Ref.Range("A1").Address(, , xlR1C1))
'Execute XLM macro
GetValue = ExecuteExcel4Macro(Arg)
End Function
Any ideas on how to get it to work, or an alternative work around? I could also temporarily import the sheet to my other file and overwrite it when a new value is entered, thus importing another sheet from the other workbook, but that seems far more complex.
I am using Excel 2013.
UPDATE: I am closer to figuring it out but I cant get it to display anything but #Value errors. My formula looks like this in excel:
=GetValue(H11,H12,B7,B4)
Cell H11 = F:\UGR\JOB DATA SHEET\
Cell H12 = JOB SHEETS 1-500.xlsx
Cell B7 = The input cell where the user enters a JobNumber (aka sheet name).
Cell B4 = B4 (The cell I want to search on the external workbook)
Cell B4 is where I think the error lies. Will this macro be able to tell that it needs to search the external file at cell B4?
I figured it out. The macro cannot be launched from within the workbook itself, it must be done from VBA.

Excel: Create summary worksheet using certain cells from other worksheets

I have a whole bunch of tabs which share a standard structure. In cells A1, B1, C1 of each tab, I have, respectively, an ID number, a first Name and a surname. There is a whole bunch of other information on each tab that is not relevant to the question.
I want to create a summary tab, with a 3-column table carrying only the ID number, first name and surname from each of the other tabs. Again, these are always in cells A1, B1, C1. I also want the id number in the summary table to hyperlink to the appropriate tab.
Is there any way to semi-automate this using cell references? Like how, in a single table, if you enter a number in a cell and drag downwards, the number will be incremented in each consecutive cell in the column. Is there any way to achieve a similar effect, but with the cell reference remaining constant (always cell A1, A2, A3) and the TAB reference being incremented? In short, is there any way to tie a particular row to a separate tab (in a way that will take care of the hyperlinking, also)? Or do I have to enter the reference manually for each table?
Not that the tabs are not labelled Sheet 1, Sheet 2 etc. They will be labelled with the name of the person whose information they hold.
[EDIT: Added ASAP option]
ASAP utilities takes the hard work out of this
Download ASAP utilities , http://www.asap-utilities.com/
Run the utility as per screenshot 1 below
Chose whether you want a live link summary, or hardcoded report
(screenshot 2)
ASAP settings
Select your A1:C1 accross sheets
Output
[Initial Post]
You can do this without a continuous VBA sub
Step 1
Define a range name to contain all the sheet names, (from this great example from David Hager)
In this example I used
AllSheets
with a reference of
=RIGHT(GET.WORKBOOK(1),LEN(GET.WORKBOOK(1))-FIND("]",GET.WORKBOOK(1)))
Step 2
Use an INDEX formula to pull out each unique sheet on your summary sheet
=IF(ROW()<=COUNTA(AllSheets),INDEX(AllSheets,ROW()),"")& LEFT(RAND(),0)
Assuming your summary sheet is at the far left (ie sheet 1) then
ROW() will be 2 in A2, so this will pull the second sheet from AllSheets
ROW() will be 3 in A3, so this will pull the third sheet from AllSheets etc
The LEFT(RAND(),0) ensures that the sheet name list updates as soon as any sheet name is changed (and VBA solution would need to monitor the sheet names for changes)
Step 3
Use INDIRECT to pull out A1, B1 and C1 for each sheet
=IF($A2<>"",INDIRECT("'"&$A2&"'!"&B$1),"")
Copy this B2 formula to the right and down as far as you expect potental sheet names
Note that this formula handles the ' that occur for sheet names with spaces etc
You could probably use the INDIRECT function.
For example, to get the value of cell A1 on sheet John, you can call:
=INDIRECT("John!A1")
So in your case you could put "John" in cell A1 of your summary tab, "A1" in cell B1 of the summary tab and in cell C1, put the following formula:
=INDIRECT("'"A1&"'!"&B1)
There is no function built into excel that will give you all the sheet names in the workbook. For this you would have to turn to VBA, the scripting facility built into Excel. If you are on Office 2007 or above, this would require you to store your workbook in a special format. Also, to execute the macro, the user has to specifically allow macro execution. The following macro will allow you to print all sheet names in the first column. An important point to note is that this code would have to be executed in the code window of the summary sheet.
Sub SheetNames()
For i = 1 To Sheets.Count
Cells(i, 1) = Sheets(i).Name
Next i
End Sub
Once you have the names of the sheet, you can dynamically link to the cells in the sheets by using the following formula:
=INDIRECT(ADDRESS(1, 1, 1, 1, A1))
=INDIRECT(ADDRESS(1, 2, 1, 1, A1))
=INDIRECT(ADDRESS(1, 3, 1, 1, A1))
The INDIRECT formula takes an address. The ADDRESS formula works as follows ADDRESS(Row_num, Column_num, Abs_num, A1, Sheet_text). Excel help will be able to answer any questions.
You could setup the formula and run the macro only when there are a lot of new sheets. The workbook can then be stored without the macro. Just keep the macro in a text file somewhere in case you need it again.
Here's a solution using a VBA UDF to get the sheet names. It includes a Hyperlink as requested.
The call to the UDF is placed in an out of the way column. I've used H for this example
Place these functions in cells A1, B1, C1, H1
A1: =IF(H1<>"",HYPERLINK(SUBSTITUTE(H1,"]","]'")&"'!A1",INDIRECT("'"&$H1&"'!R1C[0]",FALSE)),"")
B1 and C1: =IF($H1<>"",INDIRECT("'"&$H1&"'!R1C"&COLUMN(),FALSE),"")
H1: =SheetByIndex()
Put this in a VBA module
Function SheetByIndex() As Variant
Application.Volatile
Dim r As Range
Dim shIdx As Long
Dim ThisShIndex As Long
Dim sh As Worksheet
Dim wb As Workbook
Set r = Application.Caller
ThisShIndex = r.Worksheet.Index
shIdx = r.Row
If shIdx >= ThisShIndex Then
shIdx = shIdx + 1
End If
Set wb = r.Worksheet.Parent
On Error Resume Next
Set sh = wb.Worksheets(shIdx)
If Err.Number <> 0 Then
SheetByIndex = ""
Else
SheetByIndex = "[" & wb.Name & "]" & sh.Name
End If
End Function
Copy formulas in A, B, C, H down as far as required
My slightly differnt approach, based on the code published here (there's a sample sheet there, too, for testing):
Option Explicit
Sub CreateHyperlinkedSheetList()
'Author: Jerry Beaucaire
'Date: 1/3/2011
Dim ws As Worksheet, NR As Long
Application.ScreenUpdating = False
With ActiveSheet
NR = .Range("A" & Rows.Count).End(xlUp).Row + 1
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> .Name Then
.Range("A" & NR).Value = ws.Range("A1").Value
.Hyperlinks.Add Anchor:=.Range("A" & NR), Address:="", SubAddress:= _
"'" & ws.Name & "'!A1", TextToDisplay:=ws.Name
.Range("B" & NR).Value = ws.Range("B1").Value
.Range("C" & NR).Value = ws.Range("C1").Value
NR = NR + 1
End If
Next ws
End With
Application.ScreenUpdating = True
End Sub

Resources