auto increment rows that belong to the same group of values - excel

in a column, i have some values like this:
|------------|----------------|
| false | abc |
| | def |
| false | mpla |
| | xyz |
|-----------------------------|
and i need to have all rows from each false row, till the next false value,
in a group, which will auto increment:
|------------|----------------|
| 1 | abc |
| 1 | def |
| 2 | mpla |
| 2 | xyz |
|-----------------------------|
which excel formula shoul i try with?

Just something to note, without any helper row: =COUNTIF(INDIRECT("A1:A"&ROW(A1));FALSE). Thought I would put it out there :)
Obviously if your column a contains pure text it becomes: =COUNTIF(INDIRECT("A1:A"&ROW(A1));"FALSE")

Add an extra row before your data (row 1) and then put the formula =C1+IF(A2="false";1;0) in the third (C) column.

As Dmitry noted, you can add an additional row at the top and use it to initialize an accumulator at zero. Each time you run into a non-blank cell, you can increment the previous value by 1.
The reason I didn't check for false, is because false is a bit tricky. If you used TRUE instead of FALSE, your formula for row 2 (onward) would be:
=$C1+IF($A2=TRUE,1,0)
I do not have access to Excel at this time, to write a VB script, but I wrote a simple Google script to populate IDs. I am sure you can do something very similar in VB.
Sample Data
Group Name ID <-- Add third column
FALSE abc
def
FALSE mpla
xyz
You can execute the script to run through the sheet and fill in the ID column.
function autoAassignGroupId() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(),
rangeData = sheet.getDataRange(),
lastColumn = rangeData.getLastColumn(),
lastRow = rangeData.getLastRow(),
searchRange = sheet.getRange(2, 1, lastRow-1, lastColumn-1),
rangeValues = searchRange.getValues(),
auto_index = 0;
for (row = 0 ; row < lastRow - 1; row++) {
if (rangeValues[row][0] === false) auto_index++;
sheet.getRange(row + 2, lastColumn).setValue(auto_index);
}
}

Related

Countif criteria with IF/OR logic across multiple sheets and columns

I've been struggling between the SUMPRODUCT and COUNTIFS formulas as there are a lot of specific dependencies in my data. Wondering if anyone can shed a bit more light on this issue.
Have tried SUMPRODUCT and COUNTIFS which give me calculations based on 1 set, but I need to include additional if/or statements.
I have the following:
| ID | Size | Dead/Alive | Duration | Days | Pass/Fil | Reason |
|----|---------|------------|-----------|------|----------|----------|
| 1 | Full | Dead | Permanent | 125 | Pass | Comments |
| 2 | Partial | Alive | Permanent | 500 | Pass | |
| 3 | Other | Dead | Temporary | 180 | Fail | Comments |
| 4 | No | Dead | Temporary | 225 | Fail | Comments |
| 5 | Yes | Alive | Permanent | 200 | Pass | |
with the following rules:
Only Count the ID/ROW if:
1) Values in column A = Full, Partial or Other
OR...
2) Values in column A = No AND values in column B = Dead
OR...
3) If values in column C = Permanent AND values in column D = >=100 or <=200
OR
4) If values in column C = Temporary AND values in column E = Pass, Fail AND column F=not blank
By my calculations, the total should be 5, but this is just a small sampling of my total data. Just not sure how to get that in Excel with either Sumproduct, Countifs or even someone suggested a Lookup function, although Ive never used that one.
Given that you have so many different conditions, I have to break it down one by one and create a few helper columns to account for each condition.
In my solution I created 10 helper columns as shown below, and I have added some sample data (ID 6 to 29) to test the solution.
I also named 7 conditions in my solution:
Cond_1 Values in column A = Full, Partial or Other
Cond_2 Values in column A = No AND values in column B = Dead
Cond_3A Values in column C = Permanent
Cond_3B Values in column D >=100
Cond_3C Values in column D <=200
Cond_3A, Cond_3B and Cond_3C must be TRUE at the same time
Cond_4 Values in column C = Temporary AND values in column E = Pass
Cond_5A Values in column C = Temporary AND values in column E = Fail
Cond_5B Column F is not blank (I did not give a name to this condition)
Cond_5A and Cond_5B must be TRUE at the same time
Please note my Cond_4, Cond_5A and Cond_5B are all related to your original condition 4), which reads a bit odd, and I am not 100% sure if my interpretation of the condition is correct. If not please re-state your last condition and I can amend my answer accordingly.
As shown in my screen-shot, the formulas in I2 to Q2 are listed in Column U. I only used MAX, AND, SUM, =, &, and/or <> to interpret each condition. Please note some of the formulas are Array Formula so you need to press Ctrl+Shift+Enter to make it work.
The To Count column is simply asking whether the SUM of the previous 9 columns is greater than 1, which means at least one of the conditions is met. If so returns 1 otherwise 0.
Then you just need to work out the total of To Count column. In my example it is 22. I have highlighted the entries that did not meet any of the given condition.
You can use only one helper column to capture all conditions in one formula, but I would not recommend it as it would be too long to be easily understood and modified in future.
{=--(SUM(MAX(--(A2=Cond_1)),MAX(--(A2&B2=Cond_2)),--(SUM(--(C2=Cond_3A),--(AND(D2>=Cond_3B,D2<=Cond_3C)))=2),MAX(--((C2&E2)=Cond_4)),--(SUM(MAX(--((C2&E2)=Cond_5)),--(F2<>""))=2))>0)}
Ps. I would also wonder if there is a formula-based solution without using any helper column...? :)

How to copy each row in excel and paste it under the copied row

I am looking for a way to copy each row in a sheet and paste it under the original row.
CURRENTLY:
1 | abc | def
2 | ghi | jkl
3 | mno | pqr
WHAT I AIM TO DO:
1 | abc | def
2 | abc | def
3 | ghi | jkl
4 | ghi | jkl
5 | mno | pqr
6 | mno | pqr
Hope this makes sense!
Here is one method which does not require fancy formulas or macros/VBA. Just copy the entire top block, in this case three rows, and then paste immediately underneath. Then sort by the first ID column, which will group the original row with its copy. Finally, generate a new ID sequence down all rows starting with one at the top. As a series of steps:
Copy original data and paste underneath
Sort new + copy data on the number ID column
Generate a new ID column starting with 1 at the first row
Maybe you can do it like this:
Copy whole table to another sheet
Create an id column for both table
Give odd id number for the main table and give even id number for the copied table
Copy and paste copied table to main table and sort main table by id and then remove id column and delete copied sheet.
With vba assuming no gaps in range
Option Explicit
Sub Testing()
Dim targetRange As Range
Dim sourceData()
With ActiveSheet.Range("A1").CurrentRegion
sourceData = .Value2
Set targetRange = .Resize(.Rows.Count * 2, .Columns.Count)
End With
Dim currValue As Long
Dim counter As Long
counter = 1
For currValue = LBound(sourceData, 1) To UBound(sourceData, 1)
targetRange.Cells(counter, 1).Resize(2, UBound(sourceData, 2)) = Application.WorksheetFunction.Index(sourceData, currValue, 0)
counter = counter + 2
Next currValue
End Sub
Source data in A1:B3

INDEX MATCH formula stops working when creating a table

Let's say I have the folowing values setup in excel:
1 | 2 | 3 |
a | b | c |
Above thess values I have a INDEX MATCH formula that looks up a translation of the numbers 1-3:
=INDEX(PartnersProjects[Name];MATCH(K1;PartnersProjects[ID];0))
K1` is the reference to value "1" and picks up "Test1" with current output:
Test1 | Test2 | Test3 |
1 | 2 | 3 |
a | b | c |
But when I convert the 2 rows with according 3 colums (1-3 and a-c) to a table, the formula in the row above stops working some how. How to solve this?
When you make the row 1, 2, 3 as the header row of a table, this forces Excel to evaluate it as a string because these becomes the names of the columns.
You have two solutions:
1- Convert the searched value (K1) to numeric before matching:
=INDEX(PartnersProjects[Name],MATCH(VALUE(K1),PartnersProjects[ID],0))
' ^^^^^^^^^
2- Convert the search range to text, but then you will need an ^array (CSE) formula:
=INDEX(PartnersProjects[Name],MATCH(K1,TEXT(PartnersProjects[ID], "0"),0))
' Ctrl+Shift+Enter ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Correlation in Excel Pivot Table

I have a significant amount of data which I must analyse in Excel (this would be much easier in a DB, I realize). Each line item has a T/F indicator for it's membership in a given category and I would like to get a correlation of volume and price for each category across months. The quantity of data I am talking about is between 8-30k records at a time. We use Excel 2010 at my office
Example data:
State | Cat.1 | Cat.2 | Cat.3 | TimeStamp | Volume | Price
WA | TRUE | FALSE | FALSE | 01/31/13 12:00 | 113.1 | 35.64
WA | TRUE | TRUE | FALSE | 01/31/13 13:00 | 65.2 | 32.52
FL | TRUE | FALSE | TRUE | 01/31/13 02:00 | 78.9 | 36.37
FL | TRUE | TRUE | FALSE | 01/31/13 23:00 | 113.9 | 39.39
Ideally what I want is a pivot table that will correlate Volume and Price for a given combination of State, Cat.1, Year, and Month.
Right now I have a Calculated field with formula: =correl(Volume,Price)
However that field returns #DIV/0 for every scenario, but if I double click to view the applicable data, I can manually do the correl() and it works fine.
Any help will be much appreciated!
Not sure if I understand your question entirely but it sounds like you want to correlate based on the value of some of your other columns. I'm assuming therefore if you used autofilter on the header row and you could filter on the states and categories you wanted you could just correlate the visible values. You might need two extra columns with =MONTH( ) and =YEAR( ) with the timestamp.
The UDF i've written below will correlate only visible columns, so go to the VBA editor (Alt F11 ) and copy this, then enter the formular below and filter your columns
=CorrelVisibleCells(F1:F100,G1:G100)
assuming F and G are your volume and price columns
Public Function CorrelVisibleCells(aRange1 As Range, aRange2 As Range)
Dim aCorrelRange1()
Dim aCorrelRange2()
Dim rc As Long
Dim clCount As Long
Application.Volatile True 'This is a volatile function as changing the filter state without changing the cell reference requires a recalc
rc = aRange1.Rows.Count
ReDim aCorrelRange1(rc) 'Largest they could be, will crop at the end
ReDim aCorrelRange2(rc)
clCount = 0
For i = 1 To rc
If Not aRange1.Cells(i).EntireRow.Hidden Then ' Can't use SpecialCells(xlCellTypeVisible) in a UDF
aCorrelRange1(clCount) = aRange1.Cells(i).Value
aCorrelRange2(clCount) = aRange2.Cells(i).Value
clCount = clCount + 1
End If
Next
ReDim Preserve aCorrelRange1(clCount - 1)
ReDim Preserve aCorrelRange2(clCount - 1)
CorrelVisibleCells = WorksheetFunction.Correl(aCorrelRange1, aCorrelRange2) 'Get Excel to do the correlation on our new arrays
End Function

Auto-concatenate in Excel

I have a huge (~950 variables) survey response spreadsheet, made 2-4x larger than it needs to be because each item's individual response options are reported in separate columns. E.g., If Question 2 is in cell A1 and has 3 response options, these are listed below the question in cells A2-C2, A3-C3, etc. Note: Only one of A2-C2, etc. is filled w/ data for each observation.
It seems clear that I could go through the spreadsheet manually and concatenate A2-C2 using code similar to this:
=CONCATENATE(IF(ISBLANK(A4),"",A4),IF(ISBLANK(B4),"",B4),IF(ISBLANK(C4),"",C4))
But, the above requires manually altering the code (questions have anywhere from 2-6 response options) and copying/pasting it through all observations for each of the 960 variables individually. Because I'd like to finish this before dying of old age, I'd love to have some way of automating the above process.
It would be easy enough to go through and insert an identifier column (w/ no data but w/ some obvious 1st row name) after each variable's last response option so the code knows where to begin looking back for data to concatenate. The code would have to know to stop whenever it hits the previously concatenated result, and begin the current concatenation w/ the subsequent column. Once it hits a certain line (say, 60? I only have ~55 observations), it could just look for the next identifier column and repeat the process.
Any ideas would be much appreciated.
I need to check for blanks so as to not have extra spaces in the data (to aid future analysis).
Hopefully the below will clarify the situation further. You're correct in your earlier comment; each question is followed by 55 rows of observations. For example:
| | Q1 | | || Q2 | ||
|-|--------|---------|--------||---------|--------||
|1| 1 | | || | 2 ||
|2| | 2 | || | 2 ||
|3| | | 3 || | 2 ||
|4| | 2 | || 1 | ||
|5| | | 3 || | ||
|6| 1 | | || | 2 ||
|7| 1 | | || 1 | ||
|8| | | 3 || 1 | ||
|9| | 2 | || | 2 ||
There isn't currently a blank column after the last response option for each question, but (as mentioned in the initial post) I can easily throw one in.
I'm not 100% sure I understand your layout, but you can greatly simplify the concatenation by using & as follows:
=A4&B4&C4
this would have the same effect as your code, and does not require the checks for blank cells.
I'll tackle the rest of the question as information becomes available.
edit: Here's my solution. I'm assuming that the questions are in row 1, and the first set of observations is in row 2, so the last set of observations falls in row 56.
type the number 1 into the cell A58
place the formula: =IF(ISBLANK(B1),A58,A58+1) into cell B58
fill this formula right all the way across all of your questions
in cell A59, enter the formula =MATCH(COLUMN(),58:58,0)
in cell A60, enter the formula =MATCH(COLUMN(),58:58,1)
in cell A61, enter the formula =INDEX(1:1,,A59)
fill all three of these formulas right for 17 cells (assuming you have 17 questions)
in cell A62, enter the formula =SUM(INDIRECT(ADDRESS(ROW(A2),A$59)&":"&ADDRESS(ROW(A2),A$60)))
fill this formula across 17 cells, and down 55 cells.
Here's how it would look for three questions:
| A | B | C | D | E | F | G |
|----|------------------------------------------
| 1 | Qn1 Qn2 Qn3
| 2 | 1 2 1
| 3 | 2 2 2
| .. |
| 58 | 1 1 1 2 2 3 3
| 59 | 1 4 6
| 60 | 3 5 8
| 61 | Qn1 Qn2 Qn3
| 62 | 1 2 1
| 63 | 2 2 2
#EJames: Thanks for the suggestion & pointer to lay out the example graphically. I need to check for blanks so as to not have extra spaces in the data (to aid future analysis).
Hopefully the below will clarify the situation further. You're correct in your earlier comment; each question is followed by 55 rows of observations. For example:
| | Q1 | | || Q2 | ||
|-|--------|---------|--------||---------|--------||
|1| 1 | | || | 2 ||
|2| | 2 | || | 2 ||
|3| | | 3 || | 2 ||
|4| | 2 | || 1 | ||
|5| | | 3 || | ||
|6| 1 | | || | 2 ||
|7| 1 | | || 1 | ||
|8| | | 3 || 1 | ||
|9| | 2 | || | 2 ||
There isn't currently a blank column after the last response option for each question, but (as mentioned in the initial post) I can easily throw one in.
Much obliged.
The fastest way:
Add an new column after column D
Put 'Q1' in cell B1
Put the following formula in: =SUM(B2:D2)
Copy the formula down to the last row
Repeat the steps above for all questions
Select all data (ctrl-*)
Copy the selection
Choose 'Paste Special' from the context menu and choose 'values'
Delete the original columns
If you want you can create a macro that does this automatically.
Here is the macro. It is my no means my best piece of coding ever. What would you expect in 15 minutes. It does the job, although it crashes when finished. ;o)
Open your excel sheet
Make a back up copy
Hit Alt-F11
Insert a new module
Paste the code below
Put the cursor inside the macro
Hit F8 to step through the code
Since you are in Stack Overflow I assume you will be able to adjust the macro to further tailor your needs.
Sub Main()
Dim ColumnsCount As Integer
ColumnsCount = Range("A1").CurrentRegion.Columns.Count
For i = 2 To 20000
Dim CurrentCell As Range
Set CurrentCell = Range("A1").Offset(0, i - 1)
If CurrentCell.Value <> "" Then
CurrentCell.Select
Selection.End(xlToRight).Select
Dim AnswersCount As Integer
AnswersCount = Selection.Column - CurrentCell.Column
CurrentCell.Offset(0, AnswersCount).Select
Selection.EntireColumn.Insert
Selection.Value = CurrentCell.Value
i = i + AnswersCount
Selection.Offset(1, 0).Select
Selection.FormulaR1C1 = "=SUM(RC[" + CStr(AnswersCount * -1) + "]:RC[-1])"
Selection.Copy
Range(Selection, Selection.Offset(100, 0)).Select
ActiveSheet.Paste
Selection.EntireColumn.Select
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End If
Next i
End Sub
Thanks for the piece of information. Apart from your way one can also use the & character for concatenation, so instead of: =concatenate(B1,” “,C1,” “,D1) you could use: =B1 & ” ” & C1 & ” ” & D1
Old post but I made this function to concatenate cells. Works similar to SUMIF.
Function CONCIF(rng As Range, criteria As Range, sums As Range)
'Function to concatenate a range of cells if the chosen adjacent cells matches
'the criteria.
'To use:
' Copy and Paste this into a module in VB Editor
' In a cell type =CONCIF(rng, criteria, sums) where:
' rng is the range of cells to match the criteria
' criteria is the value you would to match
' sums is the range of cells to concatenate if criteria matches
' To change what is put between the concatenations, edit the " / " below and put
' whatever you would like in between the quotes.
' Enjoy! -RP
Dim rCell As Range
Dim concat As String
Dim dist As Integer
dist = sums.Column - rng.Column
concat = ""
For Each rCell In rng
If rCell = criteria Then
If concat = "" Then
concat = rCell.Offset(0, dist).Value
Else
concat = concat & " / " & rCell.Offset(0, dist).Value
End If
End If
Next rCell
CONCIF = concat
End Function
Or if you want just a simple way to select a horizontal range and have it concatenate the non-blank cells:
Function CONCIF(rng As Range)
Dim rCell As Range
Dim concat As String
Dim dist As Integer
dist = 0
concat = ""
For Each rCell In rng
If rCell.Value <> "" Then
If concat = "" Then
concat = rCell.Value
Else
concat = concat & ", " & rCell.Value
End If
End If
Next rCell
CONCIF = concat
End Function

Resources