I have a worksheet where data is updated from an external source. The page contains data from today going out 20 days. I have a named range for each column i.e. Today ($D$4:$D$50), Tomorrow ($E$4:$E$50), etc, etc. My issue is that sometime the data from the external source does not contain data so nothing is populated in the columns. However, when there is data being returned again the name ranges are automatically changing i.e , Today changes to ($F$4:$F$50). No new columns are being inserted or deleted.
How can I specify / force the name ranges always to stay the same i.e. Today is always column E, I thought that was the point of the $.
Thanks.
you could try this formulae for your named range formula.
In Name Manager, edit your named range and pop a modified version of the formulea below into the refers to: field.
The modifications will be to the numbers within the address() function. The first value is the row number, the latter is the column number, so Column A = 1, Column B = 2 and so forth.
=INDIRECT(ADDRESS(1,13)&":"&ADDRESS(50,13))
It then uses the indirect function plus a concatentation of the 2 address functions to change formulae to a cell reference that the named range can use.
So the example above, means my named range will go from M1:M50.
Related
I am getting data from SQL Server into an Excel sheet. Its a customer table containing 20 records. The columns are Customer Code, Customer Name and Customer Short Name.
What I need is instead of data coming in rows (from row 2 to row 21)... it should come in columns.. i.e. 1st three rows of column A contains respective headers (code, name and short name) and column B first row contains value of code, second row value of name and third row value of short name... same continue to column C, D, E..... till all 20 records..
Is it possible in excel?
In Excel, you can easily transpose the array with your data. Consider the following sample data in the range A1:C4:
You could now select the entire range and copy it via CTRL+C -> Paste -> Transpose (T). A second possibility would be to enter the following formula in, e.g., cell E1: =TRANSPOSE(A1:C4). This is a dynamic array formula in the current version (Microsoft 365). If you have an older version, you have to enter the formula as a legacy array formula by confirming the formula with Ctrl+Shift+Enter.
The result is as follows:
Edit: Dynamic setting of range
Theoretically, assuming that the data structure remains the same in terms of the number of columns and rows, the formulaic approach will update the transposed array accordingly as the original data is updated. In the specification above, the range A1:C4 is hard coded. While it is very likely that the number of columns will remain the same (could also be dynamically adjusted), in practice additional rows could be added/deleted from the data. In this case, you can specify the number of rows dynamically, which solves this problem:
=TRANSPOSE(INDEX(A:C,1,1):INDEX(A:C,COUNTA(A:A),3))
I have an excel file. I don't want to write any VBA code, as I don't necessarily want to run a macro for the process to work; I want it to automatically update information as I change one cell (the "Date" cell on the second sheet/photo).
So, basically I have a tracker that I will use to determine for any given date, how many tasks do I have issued to each company (military companies for context). It'll help me understand who has the least amount of tasks in general and what percentage of every company is dished out to tasks. I have a tracker of those issued tasks that looks like this:
My next tab looks like this:
It uses a COUNTIF (COUNTIF(all cells in that day's column on the first sheet/photo except the header, "Company's name")) to determine how many tasks any company has within that day; that's the "RAW" number. The "PERCENT" divides the "RAW" number by how many total people they have in the company; it already works as needed. My goal is to type in a date into the cell beneath "Date" and have the cells to the right of "RAW" automatically inform me for that date typed in. The "PERCENT" already does its magic.
I just don't know how to have the "RAW" cells' formula reference all cells underneath a date on the first sheet/photo after typing that date into "Date" on the second sheet/photo. I was considering an offset, but I'm not sure how to offset a range from the formula of another cell: A2:1000 if the formula of another cell [Date] references A1, and have those RAW cells reference change to DC2:1000 if that Date cells value or reference changes to DC1.
Use MATCH to find the date in the row of dates and insert this into OFFSET, as the COLUMNS argument, to say how many COLUMNS to the right you need to move, to count over the correct range for the selected date.
Say you had your selected date is in Sheet1!D2:
And your companies' tasks in sheet2, with the dates from column B1 onwards, and company HHC spans rows A2:A7:
You want to find the column containing the selected date using:
=MATCH(Sheet1!D2,Sheet2!1:1,0)-1) 'returns 9
The adjustment of minus one is that dates actually start in column B not A in row 1.
You know HHC spans Sheet2!A2:A7, in this example, and you now know you want to move 9 columns to the right of this to do your count.
Using OFFSET and the columns argument (9) yields Range J2:J7
OFFSET(Sheet2!A2:A7,,MATCH(Sheet1!D2,Sheet2!1:1,0)-1)
Inserting this into your COUNTIF, as the source range, with "HHC" as the criteria:
=COUNTIF(OFFSET(Sheet2!A2:A7,,MATCH(Sheet1!D2,Sheet2!1:1,0)-1),"HHC")
This is then the formula that would go in cell Sheet1!C1 next to RAW.
The same principles apply to your other companies. Define the start range for the company, use MATCH to determine the number of columns to OFFSET by, and then wrap it all in a COUNTIF.
A match being found depends on:
Date being present in search range;
That dates are of the same datatype in both sheets (i.e. dates in both sheets or strings in both sheets).
There are a lot of posts that relate, but I haven't found one quite like this. I am currently going through excel to help out in speeding up a process a little more.
The excel file has two spreadsheets. One is data the second is the summary.
On the data spreadsheet, I have the first column as names, and the next 7 columns with data values (Not all filled).
Name Data1 Data2 Data3 Country Address
VA 123 456 621 USA ExampleSt.
MD 123 France 123Street
DC 621 Korea 999Avenue
UseCol Value
Data2 456
Data3 621
Data1 000
My question is, I am given the value "621" (which can appear in multiple columns, but won't appear in ). I am given which set it should be in "data1, data2, data3...". How would I go about finding the name with that information? No VBA, only through excel.
I got stopped here with this code.
=INDEX(A1:D4,MATCH('621',*What do I put here*,0)
For that middle section, the reason why it is a problem is because I'm given which data column to use in another spreadsheet.
EDIT
So, I have followed what Tim Williams has said about using the offset. However, now I have a second column I am trying to get to. So the code that I used to get the Name is as follows
=IFERROR(INDEX(A2:A4,MATCH(B7,OFFSET(A2:A4,0,MATCH(A7,B1:D1,0)),0,1),"ERROR")
What changes do I have to make to the OFFSET portion to now look for the Country, or the Address cell? I believe the only part I need to change is that inner "MATCH" function. Should I do MATCH(A7,B1:D1,0)+3 to get to Country column? Thank you.
This worked for me as long as each number can only appear once per column.
EDIT: for getting the matching value from other columns you only need to adjust the first part of the formula.
The parameter you are missing is your lookup range in which you are trying to find the row that contains 621. Simply reference the desired column range, or create a named range and reference that.
WITH A GIVEN RANGE
I created a named range for the NAME column called "NAMERANGE".
I created a named range for the DATA1 column called "DATA1RANGE".
Using this formula I can retrieve the name if any of the row containing the given value in the given column range:
=INDEX(NAMERANGE,MATCH(621,DATA1RANGE,0))
Replace the value, and Data Range as needed.
WITH A DYNAMIC RANGE
If you need to dynamically choose the data range, you can use the INDIRECT() function to generate a reference to your desired lookup column. For example, in R1C1 style references, to get the DATA3 column, you would use the following formula:
=INDIRECT("C"&4&")
So in R1C1 style, given that you want to search in the 2nd data column (which is the third column of the spreadsheet), your formula could be:
=INDEX(NAMERANGE,MATCH(621,INDIRECT("C"&3),0))
I have two workbooks, a source file and an output file.
The source file contains information which occupies some drop-down lists in the output file.
For each drop-down list I have two 'names' (in the name manager) linked to it. For instance, the name 'SchemeID' in my output file refers to the same name in my source file. It consists of several rows/columns of data, and that populates my drop-down list.
There are some repeats in the source file (e.g. different names associated with the same number) which are appearing in the drop down lists, and I'd like to get rid of them so the list only displays unique values. Is it possible to do this using data from different workbooks?
The easiest way is oging to be to go to the source workbooks, Data Ribbon -> Remove Duplicates. Anything else will require a couple of in-between data sheets or VBA to do cleanly. If your data doesn't change option this manual method should be fine.
EDIT as you seem restricted from editing the Source File
In a different sheet (let's say Sheet2) you will need a formula which pulls in all of your data from your 2 source Names. To my knowledge there is no clean non-VBA way to combine to Named Ranges, so we will need to do this by dumping the data down to a sheet, and then picking it up again.
There are a lot of ways to do this, but I'm going to pick the one broken down to the most steps; it will be a pretty messy sheet, but you can hide it if you need to, which shouldn't be a huge concern as a non-VBA method will need a data dump sheet anyway.
In Cell D1, we will put the number of rows in SchemeID, as follows:
=ROWS(SchemeID)
In Cell D2, we will put the number of rows in SchemeID2 (which I assume is the name for your second list, which you didn't specify):
=ROWS(SchemeID2)
In column B we will be dumping in the data from both named lists, without sorting or eliminating duplicates. Do this as follows, starting at A1 and dragged down (if you want headers this gets a little trickier, so I will assume no headers).
=IF(ROW()<=$D$1,INDEX(SchemeID,ROW()),INDEX(SchemeID2,ROW()-$D$1)
This says - if the row is not more than the total entries in SchemeID, then pull the value from SchemeID at the current row #. Otherwise, pull the entry from SchemeID2, at the current row# less the total rows in SchemeID (so if we are at row 10, but SchemeID ends at row 4, then row 10 will pull the 6th entry from SchemeID2).
Now in Column A, we will be checking to see which row is a duplicate, as follows starting at A2 [A1 is hardcoded as 1]:
=IF(ISERROR(MATCH(B2,$B$1:B1,0)),A1+1,A1)
This checks to see if there's a duplicate of the current value in column B, in the rows above the current row. If there is, it keeps the same index # as the row above (which will be ignored when we use this as the index key next). If there's no duplicate, it adds 1 to the index number.
In cell D3, put the following formula to track how many unique IDs there are:
=MAX(A:A)
Next, in column C, put your new list, which pulls from column B for as many unique values as there are [drag down]:
=VLOOKUP(ROW(),A:B,0)
This is your new non-duplicate list. To make a clean reference to it, create a new named range with the following formula:
=INDIRECT("'Sheet2!R1C3:R"&'Sheet2!$D$3&"C3", FALSE)
This will simplify to [Assuming 20 rows of data in column C, bsaed on what D3 says]:
='Sheet2!R1C3:R20C3'
Which, in the R1C1 method of referencing, means Sheet2!C1:C20.
This new named range should be what your dropdown lists refer to on your other tab.
I need some help with a macro/vlookup. Originally, I recorded the macro and just did the VLOOKUP manually thinking that would always work. Lately, it hasn't been functioning properly (and I'm not sure why except that it's possible columns are not always in the same place from time to time). Is there a way to write this macro out so that it will work each time?
Here is what I'm trying to do:
I have a master spreadsheet and a vacancy spreadsheet. The master spreadsheet has information that I need to move to the vacancy spreadsheet. Not everyone on the master spreadsheet is listed on the vacancy spreadsheet (and vice versa) nor is either in a specified order. I already have a macro that adds the column names I need to the vacancy spreadsheet so that's set. I just need to get the information in there.
I want something that does the following:
Take the employee number from the vacancy spreadsheet and search for it in the master spreadsheet, then copies the information from specific column names (off the Master spreadsheet) into the columns (of the same name) on the Vacancy spreadsheet
Ex: employee number 12345 is on the vacancy spreadsheet. The macro searches the Master Spreadsheet for employee number 12345, then moves the information (within the Master Spreadsheet) from the columns Category, Center Name, Job, Location, Code, Tracking, Reason, Salary over to the columns of the same name on the vacancy spreadsheet.
There are many more columns that I need the information from, but that's a sampling. These spreadsheets are huge with tens of thousands of rows of data. Any assistance you can offer would be greatly appreciated!
I hope this all made sense.
Edit based on workbook file examples
In the SAMPLE Milestone Report.xlsx file, column M, place the following formula:
=INDEX('[SAMPLE Master Active.xlsx]Sheet1'!$1:$4,MATCH($A2,'[SAMPLE Master Active.xlsx]Sheet1'!$A:$A,FALSE),MATCH(M$1,'[SAMPLE Master Active.xlsx]Sheet1'!$1:$1,FALSE))
You can then copy & paste this formula across the remainder of the rows/columns. Some of them are going to return #N/A because the column labels don't match exactly. A similar error would return if the Employee Number could not be found.
The Index function refers to rows 1:4 of the Master Active workbook, sheet 1.
The next argument uses the MATCH() function to find the row # of the employee number in column A of the Master Active Workbook, sheet 1.
The next argument uses the MATCH() function to find the column # of the column label, in Row 1 of the Master Active workbook, sheet 1.
So this way we are able to refer to the range containing all data in your Master Active workbook, and dynamically identify the ROW in which the employee number exists, and the COLUMN in which the column label exists. The Index function then returns the value from this intersection.
Original Answer
The VLOOKUP function requires three arguments with an optional fourth argument.
Lookup_Value - this is the value you're searching for
Table_Array - this is the range/table in which you're searching for lookup_value
Column_# - the formula will return the value in matching row, for this column #, within the table_array.
Range_lookup (optional) - tells Excel whether to return an approximate match or an exact match. I have never needed to use approxiamte match, so I always set this to False.
What you need to do is make the Column_# a dynamic value, based on some other criteria. You can probably do this with the MATCH() function.
The following examples use worksheet function conventions, but shoould easily translate to VBA.
=VLOOKUP("steve", "A:C", 3, False) will return the value in column 3 from the row where "steve" is found in column A.
But assuming your data will not always be in column 3... lets say you are looking for "Category" and it might be in any column, but you know that the ccolumn labels will be in row 1. Then, instead of "3" in the VLOOKUP... formula, you would do:
Match("Category",'Vacancy_Sheet_Name'!1:1, False)
so your end resulting formula would be:
=VLOOKUP("steve", "A:C", Match("Category",'Vacancy_Sheet_Name'!1:1, False), False)
In vba, this would be:
= Application.WorksheetFunction.Vlookup("steve", "A:C", Application.Match("Category",Sheets("Vacancy_Sheet_Name").Range("1:1"),False), False)
An important note: With VLOOKUP it is ALWAYS looking in the first column of Table_Array for the Lookup_Value. If the structure of your data has changed, and the lookup_value is no longer in the FIRST column, VLOOKUP is not the appropriate function to use. In cases like these, it will probably be necessary to use a combination of INDEX() and MATCH() functions, because VLOOKUP will not work.