I am creating an excel workbook with finances for a company. In this workbook is a sheet with the income statement and a sheet with parameters.
In the sheet with parameters is a cell with the number of quarters how long a service contract of a product of the company is expected to last.
In the sheet with the income statement I want to sum as much cells as the number in the parameters sheet.
e.g. "Parameter"-sheet cell B7 has the number 4. Now in the "Income statement"-sheet I want the sum from cells C8 to 4 columns to the right (because Parameters!B7 = 4). But if I change the number in Parameters to 5 it has to take automatically 5 columns to the right in the Income statement.
I have tried with changing my Excel to R1C1, but I have no clue how to create this. With or (if possible) without VB.
It has to be something like this:
=SUM(R8C3:R8C[+Paramaters!R7C2])
There are a couple of ways of doing this. The first would be offset. Your offset formula is based off this format.
OFFSET(REFERENCE CELL, NUMBER OF ROWS TO MOVE, NUMBER OF COLUMNS TO MOVE, HOW MANY ROWS TO RETURN FROM THE NEW POINT, HOW MANY COLUMNS TO RETURN FROM THE NEW POINT)
Positive moves your down or to the right. Negative values move your left or up.
So in your case you would be looking at something like:
=SUM(OFFSET($C8,0,0,1,'Parameters'!B7))
Now I did not lock the 8 in case you were planning on copying down and wanted a new row for each line you copied down and did not want C8 to always be the same reference point. However there are ways around that and keep $C$8 if you prefer.
Now having said that, if you are just using offset a few times, by all means go ahead it wont slow things down. However if you are using it quite frequently, it will slow things down as it is a volatile function that will recalculate anytime any information is changed on the worksheet.
Now to get around that we have options!
You could also go with the INDEX option. The index option, since it returns a cell address behind the scenes, could be used as follows:
=SUM(C8:INDEX(8:8,COLUMN(C8)+'Parameters'!B7))
Related
Currently, I am trying to calculate daily averages of the availability and performance of machines. In the raw data, each machine has a different number of data points that are needed to make an average from.
Is there a way to get VBA to auto-detect the group of rows, and from then, take the average of the data in those rows?
At the moment, I have it being completed in an inefficient and buggy way held together by duct tape. The ActiveCell moves down until it finds a non-blank cell. It stores the value of the cell into an array and adds more data until it reaches a blank row. Then, it writes the value to the average column, clears the array, and moves down until it reaches a non-blank cell.
I am aware that ActiveCell.select is a terrible way to code, but I don't know of any more elegant ways to accomplish this task.
A sample of how the data will look
If you know there will not be duplicated machines, AverageIfs() is a great option, just make sure to add an And() to check current row and next row as seem below.
If there may be duplicated machines, you can use XMatch() to find the first empty row, and use either indirect() to build your AverageIfs() formula (like i did... but only useful if your data will always be in the same place) or use XMatch() along with Offset() and Sum() if you need the data to move more easily. One drawback is requiring a blank row at the top of the data, but this could be worked around with an additional if statement.
Please note: Yellow cells indicate where the formula was pulled from.
I have to work with different checklists in different Excel workbooks in order to organize the progress.
I made a summary where I set a counter in the number of items that I am missing for different workbooks using the formula shown here:
=SUM(LEN(XXX)-LEN(SUBSTITUTE(XXX,"pending","")))/LEN("pending")
However, in order to not have to consult to each of the workbooks to find out which items are pending to complete, I am requesting some guidance to understand if it's possible to say that:
If item in cell is pending, extract the name to a different cell in my summary.
Here's an example workbook:
Summary example
Thank you
I have Comment and a partial solution.
I am ignoring the the cross workbook issues for simplicity.
Get the basics working and deal with that later.
In the formula
=SUM(LEN(XXX)-LEN(SUBSTITUTE(XXX,"pending","")))/LEN("pending")
the sum function is not used correctly. Sum add up all the numbers in
a list and/or range of cells. You have a expression. It will work but is not needed.
=(LEN(XXX)-LEN(SUBSTITUTE(XXX,"pending","")))/LEN("pending")
should work.
As for the sum of the item tagged with "pending" that can be done with a couple of extra rows that would be hidden in your final sheet.
In the sample sheet. Rows 4 and 5 are intermidate calculation rows that will be hidden for final display.
Row 4 has the same relative formula :
=if(B3="pending",B2,"")
for all cells. It copies the data in row 2 only if row 3 has the word "pending".
The objective is to concatenate all of the non blank details
into one cell. I chose a solution that would with Excel 2003+. (2019 could use TextJoin() as an alternative solution)
in row 5 Cell b5 has
=if(len(B4)>0,B4,"")
Starting with C5 the rest have the relative formula
=if(len(B5)>0,if(len(C4)>0,B5&"+"&C4,B5),C4)
This progressively concatenates the cells together ignoring blank cells.
F5 has the answer needed
C8 has the
=COUNTif(B3:F3,"pending")
To count the number missing
and D8 just points as F5 to pick up the results.
For presentation purposes hide rows 4 and 5.
I am currently automating a dashboard creation and I've hit a bit of a roadblock. I need some code that will go through about 7000 rows of data and return the highest value in a certain column for each specific item. The data is copied from a pivot table and so is broken down into row sections, I have attached a mock of what it looks like.
I need the highest value in Column G for each portfolio, and will need to use the portfolio code (e.g. XY12345 - They are always 7 characters) to map that value to the dashboard.
My issue is, each portfolio has a different number of rows for the values, and some have blank cells between them, and therefore I am stumped. I was hoping to use Column J to count the number of rows for each portfolio (as there are no breaks for the portfolios in this column) and then use a loop to loop through each portfolios rows of values, based off the Column J count, and then return the highest row value for each portfolio. Problem is I'm new to VBA and have been teaching myself as I go, and I've yet to use a loop.
Many thanks,
Harry
If I understand correctly, you're looking for the largest value in Column G.
I'm not sure why you think you would need VBA for this.
Get the maximum value of a column
You mentioned that you're concerned about each column not having the same number of cells but that's irrelevant. as SUM ignores blank cells, so just "go long", or - find the maximum of the entire column.
To return the largest number in Column G you could use worksheet formula :
=MAX(G:G)
The only catch is that you can't place that formula anywhere column G or else it would create a circular cell reference (trying to infinitely add a number to itself). let's pit that formula in cell F1 for now (but anywhere besides column G would do fine).
Find the location of a value
Now that you know the largest value, you can determine where it is using a lookup function such as MATCH or VLOOKUP. Like with so many things in Excel, there are several ways to accomplish the same thing. I'll go with MATCH.
Replace the formula from above (in F1) with:
=MATCH(MAX(G:G),G:G,0)
This will return the row number of the first exact match of the maximum value of Column G.
As for the third part of question: returning the code like X12345 where the value exists, will be a little tricky since your data is not organized in a logical tabular style (tabular meaning, "like a table").
Your data is organized for humans to look at, not for machines to easily read and manipulate it. (See: Office Support: Guidelines for organizing and formatting data on a worksheet)
Basically, when organizing data in rows, all relevant information should be on the same row (not a subjective number of rows behind). Also, you have the number combined with other information.
My suggestion for a quick fix:
Right-click the heading of Column C and choose Insert to insert a blank column.
In C2 enter formula: =IF(B2="",C1,LEFT(B2,7))
Copy cell C2
Select cells in column C all the way to the "end" of your data, where ever that is (not the end of the worksheet). For example maybe you would select cells B2:B1000)
Paste the copied cell into all those cells.
Now, you can again modify the formula in F1:
=INDEX(C:C,MATCH(MAX(G:G),G:G,0))
This will return the value from Column C in the same row that the maximum value of Column G is located.
This is known as an INDEX/MATCH formula.
Hopefully this works for you in the interim until you can organize your data more logically. There's lots of related information and tutorials online.
So, I've searched for an answer to this, but I can't find anything. Hopefully some Excel guru out there has an easy answer.
CONTEXT
I have a sheet that has two columns; a list of airport codes (Col A) and a list of fuel gallons (Col B). Column A has a bunch of duplicate entries, column B is always different. It's basically a giant list of fill-up events for aircraft over time at different airports. The airports can be the same, because it's one row per fill-up event.
PROBLEM
What I want to do is have a formula that takes the enter data set, finds all identical entries in Col A, sums the Col B values for the matches, and spits out the result on a separate sheet with one entry for every set/match.
OTHER STUFF
I do not have a reference list for Column A and I would rather not create one since there are thousands of entries. I would like to just write a formula that does all this at once, using the data itself as the reference.
All the answers I find are "create a reference list on a separate sheet", and it's driving me crazy!
Thanks in advance for any help!
-rt
Sounds that you need a formula version of remove duplicated for column A, and a simple sumif for column B.
Column A
=IFERROR(INDEX(Data!A$1:A$1000,SMALL(IF(
MATCH(Data!A$1:A$1000,Data!A$1:A$1000,0)=ROW(Data!A$1:A$1000),ROW(Data!A$1:A$1000)),ROW())),"")
Array Formula so please press Ctrl + Shift + Enter to complete it. After that you might see a {} outside the formula.
Column B
=SUMIF(Data!A$1:A$1000,A2,Data!B$1:B$1000)
Just change the range for your data.
Reminders: The formula in columnA should starts from Row#1, or you have to add some offset constant for adjustments.
Since the returning value of MATCH() represents the position of the key in the given array. If we wanted it to be equal to its row number, we have to add some constant if the array is not started from ROW#1. So the adjustment of data in Range(B3:B1000) is below.
=IFERROR(INDEX('Event Data'!B$3:B$1000,SMALL(IF(
MATCH('Event Data'!B$3:B$1000,
'Event Data'!B$3:B$1000,0)+2=ROW('Event Data'!B$3:B$1000),
ROW('Event Data'!B$3:B$1000)),ROW())-2),"")
Further more, the range should exactly the same as the data range. If you need it larger than the data range for future expandability, an IFERROR() should added into the formula.
=IFERROR(INDEX('Event Data'!B$3:B$1000,SMALL(IFERROR(IF(MATCH(
'Event Data'!B$3:B$1000,'Event Data'!B$3:B$1000,0)+2
=ROW('Event Data'!B$3:B$1000),
ROW('Event Data'!B$3:B$1000)),FALSE),ROW())-2),"")
Lastly, I truly recommended that you should use the Remove Duplicated built in excel since the array formula is about O(n^2) of time complexity and memory usage also. And every time you entered any data in even other cells, it will automatically re-calculate all formulas once the calculation option in your excel is automatic. This will pull down the performance.
I have an excel spreadsheet with several columns, each representing different variables collected from various patients (rows). One of the columns is the unique medical record #, another is a unique visit identification #. The problematic one is "age." I must have inadvertently dragged and replaced the ages of about half of my subjects, since I doubt that >3000 of my 6000 patients are 54 years old.
I have the original file with correct ID# and age pairs, but I've done considerable work on this file and cannot start over. Is there a way in my new file to look at the ID# in column C, go to the old excel file, find that ID#, go over 3 cells to column F (age), copy that age value, go back to the new excel file and paste the correct age for each ID#?
I cannot simply sort both files by ID# and copy/paste all of the ages as a number of the cases have been intentionally removed and so the ID#s wouldn't match up because the total N is different.
I also have SPSS and R available to me, although I'm not particularly proficient with either.
Just, as an example, here's what the two spreadsheets look like:
http://imgur.com/OjZsLEJ
I've manually highlighted the bad values, but in reality there are 3000+ of them and manually checking would be very time consuming.
Thanks in advance!
A VLOOKUP function should work here:
=VLOOKUP(C3,[OldWorkBook.xlsx]Sheet1!$C:$F,3,FALSE)
If you place this function in Column C, Row 3 of the New Workbook and then change "OldWorkBook.xlsx" in the function to reflect the name of your old Workbook, it should return the correct value from your old Workbook.
You can then copy that formula and paste it into the remaining cells in that column.
If the values are correct, you can copy them, Right-Click and select "paste values" to solidify them in your new workbook.
If I've understood your question, that should fix the problem. If not, please let me know.
You can do that with a VLOOKUP formula.
It should look like this (check if the cell references are right, and also the file and sheet name).
You should put this in a new column in your "NewFile".
The formula references the "OldFile" and should bring the value for the "F" column in the "OldFile" whenever the values for the "C" column are the same.
This example would be for the second row of the file (I am assuming the first row are column headers).
=VLOOKUP(C2,'[OldFile.xls]Sheet1'!$C$2:$F$6000,4,FALSE)