Is there a way to automatically copy and insert a line in an Excel sheet if the user selects a specific value from a drop down list?
Suppose the drop down list is column 2 (product) and takes values "Apple" & "Pear". Each time a user selects Apple, the lines should be duplicated. For instance
Name
Product
Price
A
Apple
1
B
Pear
1
C
Apple
1
If the user selects Apple, the end result should be
Name
Product
Price
A
Apple
1
A
Apple
1
B
Pear
1
C
Apple
1
C
Apple
1
If so, could anyone tell me how to do it ?
I have written this code so far but no new lines are being created
Sub Addline()
Dim Rng As Range
Dim LR as Integer
LR = Sheets("Customer").Range("A7").EndXlDown.Row
For i = 7 to LR
Set Rng = Sheets("Customer").Range("E" & i)
If Rng = "Apple" Then
Rng.Offset(Rowoffset).EntireRow.Insert Shift:= xlShiftDown
End If
Next
End sub
Then in worksheet_change()
Call Addline
If i modify line in the sheet, it ends up adding several lines instead of only one.
Related
Here is my problem, I have those data on my Sheet1
A B C
1 Name Account Amount
2 John HSBC -20000
3 Ashley JPM 140000
4 Rose BAML 70000
5 John DB 10000
6 Rose Barclays -25000
7 Ashley JPM -3000
My goal is to use vba in order to sort lines and group them by name and amount. The result that I'm looking for in Sheet2 is :
A B C
1 Name Account Amount
2 John HSBC -20000
3 John DB 10000
4
5 Ashley JPM -3000
6 Ashley JPM 140000
7
8 Rose Barclays -25000
9 Rose BAML 70000
I already succeeded in taking the negative values first, but I still have difficulties in taking the rest and leave a blank line between groups.
Here is the code that I started :
Option Explicit
Sub sort_account()
Dim list_amount As Range, amount As Range
Dim b As Integer
Worksheets("Sheet1").Activate
Set list_amount = Worksheets("Sheet1").Range("C2", Range("C2").End(xlDown))
For Each amount In list_amount
If amount.Value < 0 Then
b = Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
Worksheets("Sheet2").Cells(b + 1, 1).Value = amount.Offset(0, -2)
Worksheets("Sheet2").Cells(b + 1, 2).Value = amount.Offset(0, -1)
Worksheets("Sheet2").Cells(b + 1, 3).Value = amount
End If
Next amount
Worksheets("Sheet2").Activate
End Sub
And this gives me as a result :
A B C
1 Name Account Amount
2 John HSBC -20000
5 Ashley JPM -3000
8 Rose Barclays -25000
I really have difficulties for the rest. Do you have any ideas ? I thank you in advance for that.
Nb : The order doesn't matter, I just want that the first values of each group is the negative amount.
Thanks!
If this were my project, I would do it in three distinct steps: Copy all the data from sheet 1 to sheet 2; Sort the data in the preferred order; Insert the blank rows, starting from the bottom.
The following code should do what you’re after.
Option Explicit
Sub sort_account()
Dim LastRow As Long, i As Long
Sheet2.Cells.ClearContents
Sheet1.UsedRange.Copy Sheet2.Range("A1")
Sheet2.Columns("A:C").Sort Key1:=Sheet2.Range("A2"), order1:=xlAscending, _
Key2:=Sheet2.Range("C2"), order2:=xlAscending, Header:=xlYes
LastRow = Sheet2.Cells(Rows.Count, "A").End(xlUp).Row
For i = LastRow To 4 Step -1
If Sheet2.Cells(i, "A") = Sheet2.Cells(i - 1, 1) Then
Sheet2.Cells(i - 1, "A").EntireRow.Insert
End If
Next i
End Sub
If your version of Excel supports Dynamic Arrays then you can do the following
This solution adds an extra row for each unique name, sorts the new data, and then blanks out the added rows.
E2 is =CHOOSE({1,2,3},UNIQUE(A2:A7),"temp",99999999). This creates an array with all the unique names in the first column, "temp" in the second column and 99999999 in the third (to be used for sorting).
F6 is =ROWS(A2:C7) the count of the rows in the data
F7 is =ROWS(E2#) the count of unique names
A10 is =IF(SEQUENCE(F6+F7)<=F6,A2:C7,INDEX(E2#,SEQUENCE(F6+F7)-F6,SEQUENCE(1,3))). This appends the original data to the new data.
E10 is =SORT(A10#,{1,3}), the appended data sorted.
I10 is =IF(F10:F18="temp","",E10#). This blanks out all the temps rows.
If your version of Excel supports LET you can do this in one cell.
=LET(data,A2:C7,
tempRows,CHOOSE({1,2,3},UNIQUE(A2:A7),"temp",99999999),
totalRows,ROWS(data),
uniqueNames,ROWS(tempRows),
outRows, SEQUENCE(totalRows+uniqueNames),
unsorted,IF(outRows<=totalRows,data,INDEX(tempRows,outRows-totalRows,{1,2,3})),
sorted,SORT(unsorted,{1,3}),
result, IF(INDEX(sorted,outRows,2)="temp","",INDEX(sorted,outRows,{1,2,3})),
result)
Looking to fill blank values in a row with the 'top' value, similar to the functionality provided by Editing>Fill>Top. The difference being that the Fill function requires you to go row-by-row rather than applying itself to a larger dataset. Example below:
Apple 1 foo
Banana 1 foo
2 foo
bar
Cherry 2 bar
3 foo
6 bar
Grape 1 foo
Would end up as the following:
Apple 1 foo
Banana 1 foo
Banana* 2 foo
Banana* 2* bar
Cherry 2 bar
Cherry* 3 foo
Cherry* 6 bar
Grape 1 foo //new values represented with *
Note that the third entry in the second column (2) was also brought down implying this could be applied to multiple columns.
The value in this would be converting a table that has the relationships Cherry>2, Cherry>3, Cherry>6 represented in the first table into a format that could be used as an associative table.
Try this short macro:
Sub FillInTheBlanks()
Dim i As Long, N As Long, j As Long
N = Cells(Rows.Count, "C").End(xlUp).Row
For i = 2 To N
For j = 1 To 2
If Cells(i, j).Value = "" Then Cells(i, j).Value = Cells(i, j).Offset(-1, 0).Value
Next j
Next i
End Sub
I thought id add my variation on this one. Works when you just want to select a range
Sub BlankCellAll()
For Each c In Worksheets("Sheet1").Range("A3:R14").Cells
If c.Value = "" Then c.FormulaR1C1 = "=R[-1]C"
c.Value = c.Value
Next
End Sub
I am trying to match up data in three adjacent columns with data in a fourth column.
This is how my data is currently organized:
ROW A B C
----------------------
1 Cat Car Red
2 Dog Bike Blue
3 Bird Car
4 Bear Car Blue
5 Fish Bike Red
6 Cow Car Red
(the values in column A are unique; the values in B and C are repeated values)
And this is how I need it to be organized:
ROW A B C
----------------------
1 Cat Car Red
2 Dog Bike Blue
3
4 Bird Car Blue
5 Bear Car Red
6 Fish Bike Red
Basically, I need columns A and B to see that column C is empty in row 3, and to insert blank cells in A3 and B3 so that each A and B value below that is moved down by one.
The spreadsheet has many of these needed insertions. Some of them will be individual insertions like the example above, but others might be 3, 4, 5, 10 insertions in a row.
Is there a formula or some kind of automated process I can use to make this happen?
Thanks!
From the example you posted, you want to push A and B down when C is blank?
Sub PushDown()
Dim X As Long
For X = 1 To Range("A" & Rows.Count).End(xlUp).Row
If IsEmpty(Range("C" & X)) Then Range("A" & X & ":B" & X).Insert xlDown
Next
End Sub
Sub clearContent()
Dim lastrow As Integer
lastrow = Range("D65536").End(xlUp).Row
For i = 2 To lastrow
If Cells(i, 4) = "" Then
Range(Cells(i, 2), Cells(i, 3)).ClearContents
End If
Next i
End Sub
I have the following dataset:
Name Code Output Type
Alice Apple -100 B
Alice Apple +60 S
Alice Banana -52 S
Alice Apple +40 S
Alice mango -5000 S
Bob Kiwi -500 B
Bob Kiwi +500 S
Bob peach -40 S
Dan Banana -50 S
Dan peach +28 S
I want to reduce this data using the following criteria:
IF records with a given name do not contain "B" in any record in column "Type" then I don't want to consider it. So the "Dan" records are out. Of the 5 Alice records, the first one has a "Type" "B" and Bob has a "Type" "B" as well.
For others, I want to see which fruit numbers don't net out to zero.
So this is what I would like to see:
Name Code output Type
Alice Banana -52 S
Alice mango -5000 S
Bob peach -40 S
Right now, First I am doing a SumIfs over Name and Code.
=SUMIFS($C$2:$C$21,$B$2:$B$21,B2,$A$2:$A$21,A2)
Then I create a column where I give the value 1 when type = B and 0 otherwise.
=IF(D2="B",1,0)
Then I am doing a Sumif to figure out which names have a "B"
=SUMIF($A$2:$A$21,A2,$F$2:$F$21)
Then I will filter the ones which don't have a B and where the SUMIFS are not zero.
Right now this is in-sheet. I intend to use these formula in a VBA macro. Is there a better way to do this? Say without creating new columns?
Assuming your columns are in the correct order as above. the below code will generate a new 5th column with 0, 1.
Option Explicit
Option Compare Text
Sub SetFilter()
Dim sh As Worksheet: Set sh = Sheet1
' YOU MUST add reference "Microsoft Scripting Runtime" from tools menu to use this object...
Dim FruitSums As New Scripting.Dictionary ' key = name of fruit, value is running total
FruitSums.CompareMode = TextCompare
Dim iR As Integer
Dim lbl As String
Dim value As Variant
'get fruit sums
For iR = 2 To sh.UsedRange.Rows.Count
lbl = sh.Cells(iR, 2)
value = sh.Cells(iR, 3)
If IsNumeric(value) Then
If FruitSums.Exists(lbl) Then
FruitSums(lbl) = FruitSums(lbl) + CLng(value)
Else
FruitSums(lbl) = CLng(value)
End If
End If
Next
' calculate the filter column
For iR = 2 To sh.UsedRange.Rows.Count
If sh.Cells(iR, 4) = "B" Then
sh.Cells(iR, 5) = 1 ' ok, is a B
Else
lbl = sh.Cells(iR, 2)
If FruitSums.Exists(lbl) Then
If CLng(FruitSums(lbl)) = 0 Then
sh.Cells(iR, 5) = 0 ' not ok, is total 0
Else
sh.Cells(iR, 5) = 1 ' ok, is not 0
End If
Else ' this case should not occur
sh.Cells(iR, 5) = -1 ' unexpected output.
End If
End If
Next
End Sub
I have a list of products listed on one worksheet, but not every product will have a value. In a separate worksheet I want it to only pull over the products that have values. I have been able to output the fist column of pizza but pizza-crust will not continue
Sheet 1 called prices
list pizza pizza-crust pizza-thin
pepper 1 5 8
beef 2
bacon 3 6
pineapple 4 9
mushroom 7 10
The macro that I have does the following
list pizza
pepper 1
beef 2
bacon 3
pineapple 4
how can i get it to fill in the data for the rest of the columns so that it would put pizza crust and then the data for each and then put pizza-thin and the data for that
below is the macro
Sub Button2_Click()
Dim column As Integer
column = 1
newrow = 1
Do Until Worksheets("sheet1").Cells(column, 1).Value = ""
If Worksheets("sheet1").Cells(column, 2).Value <> "" Then
Worksheets("sheet2").Cells(newrow, 1).Value = Worksheets("sheet1").Cells(column, 1).Value
Worksheets("sheet2").Cells(newrow, 2).Value = Worksheets("sheet1").Cells(column, 2).Value
newrow = newrow + 1
End If
column = column + 1
Loop
End Sub
thanks
Select cell B2 and run my unpivot add-in (available here). It should be easy after that to add the additional zero columns.