Referencing a sheet by index number - spreadsheet

I've got a LibreOffice Calc spreadsheet that I use to keep track of my accounts receivable at work. Each sheet lists invoices and their status (paid, unpaid, etc) as well as info about each invoice. I'm trying to create a Summary sheet that lists certain data from each sheet. Creating the sheet manually is easy, but I'm trying to "automate" the process. I want the summary page to auto-update if I add a new sheet (or remove one) as I add and remove accounts to the file.
I know that LibreOffice assigns each sheet an index number that I could refer to in some sort of formula, but I cannot find a function that I can use to refer to that index number when getting a value from a cell within it. One would expect that a function like Sheet(2) would reference the second sheet, but, alas, that is not so!
I've tried using the indirect and address functions without success, but I'm not sure if I'm not understanding these functions or if they're not appropriate for what I'm trying to accomplish.

This has been a missing piece in Calc for a long time. The preferred solution is to write a user-defined function. Spreadsheet formulas do not access sheets by index number but Basic can.
The following function is from https://ask.libreoffice.org/en/question/16604/how-do-i-access-the-current-sheet-name-in-formula-to-use-in-indirect/.
Function SheetName(Optional nSheet)
If IsMissing(nSheet) Then
SheetName = ThisComponent.getCurrentController().getActiveSheet().getName()
Else
SheetName = ThisComponent.getSheets().getByIndex(nSheet-1).getName()
EndIf
End Function
Then get a relative address of the first sheet cell A1 like this.
=ADDRESS(1,1,4,,SHEETNAME(1))
A slightly different function is given at https://forum.openoffice.org/en/forum/viewtopic.php?f=9&t=49799.

Related

Is there a way to change a vlookup table_array in VBA?

Basically, I am trying to use VBA to change the VLookup table_array from one tab to another. Currently the VLookup value is something like this
=+vLookup($A4,'02.19.21'!$A$1:$O$9000,F$1,False)
02.19.21 is the name of a tab the data is pulling from, but every week a new tab is created with the most recent data, so the next week the data will need to pull from a new tab that will get created called "02.26.21"
I need vba to change '02.19.21' to '02.26.21', which is where the new data will be pulled from
Edit, I have tried doing a macro recorder, but the issue is that the data is changing weekly, meaining, if I record and change the date to 02.26.21, then when i need to do it for the next week, march 5th, it would not return that data.
I tried the date function in VBA and then used it as a string, since the vlookup would be looking at a tab that is called 02.26.21, but got errors when I did that.
I would consider using a named range for your vlookups instead of a direct sheet+range reference.
See here for named ranges for example: https://www.contextures.com/xlnames01.html
So your vlookup goes from this:
=+vLookup($A4,'02.19.21'!$A$1:$O$9000,F$1,False)
to this:
=+vLookup($A4,LookupTable,F$1,False)
So then when your code needs to change the source sheet, you can do something like:
ThisWorkbook.Names("LookupTable").RefersTo = _
ThisWorkbook.Sheets("02.26.21").Range("A1:O9000")

Excel VBA - Pull information into user form to update

I am trying to create a userform that allows the users to update issues stored in a specific sheet (called Issues List). I have built a dropdown list using data validation that allows the user to select the unique issue name from a list. I have created a button next to that dropdown which opens up the userform and correctly imports the issue name identified from the dropdown.
What I need to figure out is, when the user form is initiated how do I have it search column B in my Issues List sheet and identify which row contains the issue selected by the user, and populate the fields of the user form with the information found in rows C-X of the Issues List sheet.
What I have been trying to use is an index match function, but have been unsuccessful in getting the code to work. An example of what I have been using is:
Resolved.Value = Application.WorksheetFunction.index
('Issue List'!$X$2:$X$1000,Application.WorksheetFunction.match
('Priority Table'!I35,'Issue List'!$B$2:$B$1000,0))
Any help would be greatly appreciated.
Thanks in advance!
When you use Worksheet Functions in VBA, you still have to pass in the ranges using VBA language:
So instead of:
'Issue List'!$X$2:$X$1000
you would use:
Worksheets("Issue List").Range("X2:X1000")
And instead of:
'Priority Table'!I35
Just use:
Worksheets("Priority Table").Range("I35")
Note that you can also refer to ranges by names, which can make coding easier and also far safer. When you insert rows in spreadsheets, Excel doesn't automatically update ranges in any VBA code. A reference to I35 will always to be I35.
Instead, define a name for cell I35 in Excel as normal, then refer to it in the code.
For example, if you name I35 as "Issue"
You can refer to the cell by:
Range("Issue")
(If it is a global variable, which it is be default as long as it's a unique name in the workbook, you don't need to use the Sheets("Priority Table") qualifier.
Refer to this documentation for more info on how to refer to ranges in Excel from VBA:
https://msdn.microsoft.com/en-us/library/office/gg192736(v=office.14).aspx

Lookup function in multiple sheets data

I have multiple sheets of data and I want to make it in one sheet (All of them are in the same workbook). Link to the excel file.
I tried to use Hlookup function in excel file, something like below:
=HLOOKUP("University",Sheet1!$A$1:$G$2, 2, FALSE).
But, since I have more than 100 sheets of data, I want to find a way to drag the function and auto generate the function below the 2nd row. I have tried to use indirect function by setting a reference column in front as below but cannot deal with it.
=HLOOKUP("University", 'INDIRECT(A3)'!$A$1:$G$2, 2, FALSE)
My next option is VB code. But, I am new to VB. Anybody can help on it?
Place your individual sheet names in column H of the Summary sheet and the row number in column I (as helper columns) and write this formula in cell A2 of the summary sheet.
=IFERROR(HLOOKUP(A$1,INDIRECT($H2&"!A1:G"&$I2),$I2,0),)
and drag to column F and down for as many sheet rows combos you have. I used 10 rows but you can obviously make it longer or shorter as neeed.
When you are done you can filter on 0 in column A and remove any lines with no data.
If your sheet names have spaces in them, you'll need to adjust the INDIRECT formula to this:
INDIRECT("'"&$H2&"'!A1:G"&$I2)
best way would be "defined names" + INDIRECT + HLOOKUP (or LOOKUP) like:
defined names
name: SList
formula: =MID(TRANSPOSE(GET.WORKBOOK(1))&T(NOW()),FIND("]",TRANSPOSE(GET.WORKBOOK(1))&T(NOW()))+1,255)
formula in cells: (this in A2 then simply autofill to G2 and thenn everything down) (you'll get a row with 0's between the sheets, which can be filtered out or deleted later (copy/paste values))
=IFERROR(HLOOKUP(A$1,INDIRECT("'"&INDEX(SList,COUNTIF($A$1:$A1,0)+2)&"'!$A:$G"),$H2,0),"")
Set H2 to 2 and for H3: (autofill down from H3)
=MAX(($H2+1)*($A2>0),2)
works perfectly for me LINK
No manual typing of sheetnames or something like that (only Column H:H as helper). Youll get rows's with 0's every time a new sheet is selected which can be filtered out. (or if you copy/paste values also can be deleted)
the +2 at ...st,COUNTIF($A$1:$A1,0)+2)&... simply tells to start with sheet 2 (if summary is the first). You may change it to +1 if you want to lookup starting with the first sheet.
Assuming you already have all 100+ sheet names typed out in column A, this will work whether or not you have spaces in the sheet names:
=HLOOKUP("University", OFFSET(INDIRECT(ADDRESS(1,1,1,1,A2)),0,0,2,7),2,FALSE)

Excel Reference External Sheet

An excel question for you gurus. I've tried searching high and low and haven't come up with an effective solution.
I'm trying to create a formula that will lookup a value in an external sheet. I'm using the SUMPRODUCT formula and it works perfectly. Formula is below:
=SUMPRODUCT(--('File\Path\[file.xlsx]SheetName!$D$1:$D$1000=$B3), --('File\Path\[file.xlsx]SheetName'!$O$1:$O$1000=$A3), 'File\Path\[file.xlsx]SheetName'!$Q$1:$Q$1000)
The issue I'm running into, however, is that the source file is updated every day. Although the workbook name stays the same, the sheet name changes. A random string gets assigned to the source sheet name each time it is updated. As such SheetName becomes SheetName ase341.
Is there a way to have the formula read the external sheet number instead of the name? I want the formula to update regardless of the sheet name. If there's no way to read the sheet position is there a way to change the sheet name via a formula in an external workbook?
Usage Example
I have a workbook (analysis) and it pulls data from another workbook (source). Source is updated every day with new data. The data in Source is updated by downloading a report from the internet and saving over the old source file. As such, the file name stays the same but whatever is inside the file is always different (including the sheet name). There is always only ever one sheet in the Source with the same number of columns, always in the same position.
There is a really neat way to refer to a block of cells in an external workbook in which the sheetname or even the block address may vary. Say we have:
=SUM('C:\Users\James\Desktop\[Book1.xlsx]Sheet1'!$B$2:$B$9)
however the sheetname may vary. First assign a Defined Name to the block in Book1 (say XXX)
Then we can use:
=SUM('C:\Users\James\Desktop\Book1.xlsx'!XXX)
It does not matter if the sheetname changes, the Defined Name will change with it!
Your issue would be most efficiently solved with VBA, but if you're just getting started this might not be the best route.
You can get the sheetname or filename with just a formula, though:
http://www.ozgrid.com/VBA/return-sheet-name.htm

Find out if a column contains a certain number

Right now I have a macro that loops through a worksheet that contains data about different machine parts performs various actions on another worksheet using that data. Now I want it to add each part number to a column in a third worksheet, but only if it doesn't already exist there. Here is my code for adding the part numbers:
Rows("1:1").Insert Shift:=xlDown
Range("A1").Value = cpn
I have the list spoted after each added part number. Is there any way better than a loop to find out if the part number already exists?
You could use the COUNTIF method. Just like this:
Application.CountIf(Range("A:A"), valueThatYouWantToSearchFor)
It will return the number of cells that contains this value.