For each loop usage in VBA and retrieving the datas - vba

I have the following data in sheet1.
TransId CustID Account Stake
1 1 NP1 10
2 1 NP1 11
3 1 NP1 12
4 1 NP1 13
5 1 NP1 14
6 2 NP2 15
7 2 NP2 16
8 2 NP2 17
9 2 NP2 18
10 2 NP2 19
11 3 NP3 20
12 3 NP3 21
13 3 NP3 22
14 3 NP3 23
15 3 NP3 24
and the following details in sheet2.
Account Agent master SuperMaster
NP1 1 5 4
NP2 9 5 6
NP3 4 3 7
NP4 8 3 2
NP5 2 7 8
NP6 8 10 2
I would need to to calculate in sheet3 that, for each customerId in table, I need to consider all the TransId and the relevant stake & Account. Then i should compare account in sheet2 and retrieve the values of agent, master and Supermaster. Therefore my final calculation in sheet3 would be,
for each CustId, transId1(stake*agent*master*supermaster) + transId2(same as 1) and goes on until TransId5, since there are 5 transactions in CutomerId1.
Kindly guide me how do I do this in VBA ? (I am new to programming & VBA)

In my opinion, the easiest way to go about this is using vlookup and pivot tables. I tried for a bit to set something up purely in vba, I know it's possible, but for me this was much easier. This will produce a table on sheet1 that you can run a pivot table off of to produce the result you want.
Sub Main()
Dim rowCount1, rowCount2 As Integer
rowCount1 = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
rowCount2 = Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("Sheet1").Range("E1").Value = "Agent"
Sheets("Sheet1").Range("F1").Value = "Master"
Sheets("Sheet1").Range("G1").Value = "SuperMaster"
Sheets("Sheet1").Range("H1").Value = "Sum"
Dim x As Integer
For x = 2 To rowCount1
Sheets("Sheet1").Range("E" & x).Formula = "=vlookup(C" & x & _
",Sheet2!A1:D" & rowCount2 & ",2,false)"
Sheets("Sheet1").Range("F" & x).Formula = "=vlookup(C" & x & _
",Sheet2!A1:D" & rowCount2 & ",3,false)"
Sheets("Sheet1").Range("G" & x).Formula = "=vlookup(C" & x & _
",Sheet2!A1:D" & rowCount2 & ",4,false)"
Sheets("Sheet1").Range("H" & x).Formula = "=product(D" & x & ":G" & x & ")"
Next x
End Sub
Then on sheet 3, using a pivot table on the data from sheet 1, you get
Row Labels Sum of Sum
1 1200
2 22950
3 9240
Grand Total 33390

Related

VBA running sum

Let's say I have 2 columns (the following table includes the result)
Product ID Price Average
1 4 5
1 4 5
1 7 5
2 3 3
2 3 3
3 9 9
I want to be able to write a VBA code to loop through the rows of Product IDs and create the 3rd column which has average out the Prices.
I guess a For statement would work, but how do I define temp variables to store each ID?
Thanks!
As Vasily and L.Dutch told, AVERAGEIF() function is all you need. If you want to loop it through all cells, you can use Do While loop like this:
Sub avg()
Dim i As Integer
i = 2
Do While Range("A" & i).Value <> ""
Range("C" & i).FormulaR1C1 = "=AVERAGEIF(C1,RC1,C2)"
i = i + 1
Loop
End Sub

How to define a range using R for loop to create graphs

I have a dataset in excel that looks like this:
MA M1 M2 T1 T2 W1 W2 Th1 Th2 F1 F2
100 1 2 2 1 2 0 0 2 2 1
100 2 0 2 1 2 2 1 2 2 0
101 1 3 0 1 1 0 1 0 1 1
101 0 2 1 1 0 1 1 1 1 1
102 1 1 1 2 0 1 0 0 2 2
102 1 2 0 1 1 0 1 1 0 3
I am trying to create a column chart for each code (100,101,102) where each code will have 2 data sets and the horizontal values will be m1, m2, t1, etc.
So in the end I want 3 column graphs. I am trying to use a for loop to create these graphs in VBA, and here is what I have been trying:
Sub MA()
Dim i As Integer
Dim row1 As Integer, row2 As Integer
For i = 1 To 6 Step 2
Dim MAChart As Chart
Set MAChart = ActiveSheet.Shapes.AddChart.Chart
With MAChart
row1 = i + 1
row2 = i + 2
.ChartType = xlColumnClustered
.SetSourceData Source:=ActiveSheet.Range("Q& row1 & : & Z & row2")
End With
Next i
End Sub
I keep getting an "Application defined or object defined" error. I am having trouble defining the range of each chart since it changes based on i. I would love to find a clean way to make a series of charts using a for loop without redefining the range/dataset each time for each different chart. Does anyone know a good way to do this??
Below is treating the whole "range" as a string which would not equate to a range
Range("Q& row1 & : & Z & row2")
Try using below, you have no need for row1 and row2. Take note of how I am building up the string that makes a valid range
Range("Q" & 1+i & ":Z" & 2+i)
Used with your code be something like, notice I have also moved your "Dim" out of the loop this does not need to created each loop but needs to be "Set" every loop
Sub MA()
Dim i As Integer
Dim MAChart As Chart
Dim row1 As Integer, row2 As Integer
For i = 1 To 6 Step 2
Set MAChart = ActiveSheet.Shapes.AddChart.Chart
With MAChart
.ChartType = xlColumnClustered
.SetSourceData Source:=ActiveSheet.Range("Q" & i & ":Z" & 1+i)
End With
Next i
End Sub
You may also want to consider the position of the charts above will create them all on top of each other.

how do I conditionally subtract in Excel?

I am trying to do the following with knowing that column A and B are data and C is the result:
A B C
1 5 (B1-A1)=4
2 3 (B2-A1)=2
3 5 (B3-A1)=4
4 7 (B4-A2)=5
5 4 (B5-A2)=3
6 9 (B6-A2)=7
.
.
.
.
How do I do this automatically in Excel or in Excel Visual Basic?
Sub sequence()
Dim i As Integer
Dim j As Integer
i = 2
j = 2
For i = 2 To 25 Step 3
Cells(i, 3) = Cells(i, 2) - Cells(j, 1)
Cells(i + 1, 3) = Cells(i + 1, 2) - Cells(j, 1)
Cells(i + 2, 3) = Cells(i + 2, 2) - Cells(j, 1)
j = j + 1
Next i
End Sub
Here is the VBA code that solves.
You must define the range in for loop, currently it is set from 2nd Row to 25th Row.
A B C
1 4 =B2-A2
1 2 =B3-A3
1 3 =B4-A4
=A2+1 5 =B5-A5
=A3+1 6 =B6-A6
=A4+1 7 =B7-A7
=A5+1 6 =B8-A8
=A6+1 7 =B9-A9
=A7+1 9 =B10-A10
You can initiate your first 3 rows with 1 and then just add 1 in the 4th row column A; drag the formula down. Subsequently, you may then subtract Column B from Column A.
The only drawback is that your column A will not be a sequence incrementing by 1 every step instead a sequence stepping by 1 on every fourth occasion.
OFFSET with ROW() is your friend for any repeating n-th row/column problem.
=B1-OFFSET(A$1,ROUNDUP(ROW()/3,0)-1,0), copied down column C.
1 5 4
2 3 2
3 5 4
4 7 5
5 4 2
6 9 7
You can use the $ in the function ($B5-$A1) and drag the cursor with the cell over the C column to the last element written.

Merge two excel files using a common column

I have two excel sheets. I have to merge the two such that the values in one match with the other. For eg.
The first excel, the 2nd excel
1 t 1 tes1
2 5 3 tes3
3 t 4 tes4
4 g
Notice that in the first column of the 2nd excel, 2 is missing, so I want the first excel to look like this,
1 tes1 t
2 5
3 tes3 t
4 tes4 g
I am new to excel. Any help on this will be highly appreciated.
Sub left_join()
Dim res As Variant
Dim i As Long, lastUsedRowSh1 As Long, lastUsedRowSh2 As Long
Dim cell As Range
Sheets(3).Cells.ClearContents
Sheets(1).Range("a:b").Copy Destination:=Sheets(3).Range("a1")
Sheets(3).Columns(2).Insert Shift:=xlToRight
lastUsedRowSh1 = Sheets(1).Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
lastUsedRowSh2 = Sheets(2).Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
i = 1
For Each cell In Sheets(1).Range("a1:a" & lastUsedRowSh1)
On Error Resume Next
res = Application.WorksheetFunction.VLookup(cell.Value, Sheets(2).Range("a1:b" & lastUsedRowSh2), 2, 0)
If Err.Number = 0 Then
Sheets(3).Range("b" & i).Value = res
i = i + 1
Else
i = i + 1
End If
Next cell
End Sub
You can even solve with a simple formula.
Foglio1
A B
1 t
2 5
3 t
4 g
Foglio2
A B
1 tes1
3 tes3
4 tes4
Foglio3
Copy the content of Foglio1 in Foglio3, then run this formula
=IF(ISERROR(VLOOKUP(Foglio1!A1,Foglio2!$A$1:$B$3,2,0))=TRUE,"",VLOOKUP(Foglio1!A1,Foglio2!$A$1:$B$3,2,0))
and drag it down. Regards.

macro to re-arrange data

I have been trying to write a macro to re-arrange the Cells in the rows and columns of Stock tables for the output I desire. Luckily the Stock Tables are generally the same each and every time (Different names and values), and the desired outcome is the same format..
Here is some example Data.
A
1 Name
2 description
3 description
4 description
5 description
6 ID#: 56284
7 Quantity in stock: 34
8 Zoom In and Configure
B
1 Name
2 description
3 description
4 description
5 description
6 ID#: 56284
7 Quantity in stock: 50
8 Zoom In and Configure
And I would like the Output to go into something like this(If possible to sheet2 starting on Cell B2):
B C E
B Being Row 1
C being Row 2 3 4 and 5 Combined
E being JUST Row 7 Stock Value I.E 50
On a single spreadsheet there would be 4 columns, and 8 rows I would have to re-arrange.. Making 32 total.
It would be great to automated this, so any help would be greatly appreciated.
Let me clarify my understanding. For each column you want the following data format:
A A
1 Name 1 Name
2 Desc1 2 Desc1; Desc2; Desc3; Desc4
3 Desc2 On sheet 2 3 50
4 Desc3 --------------->
5 Desc4
6 Id#: 56284
7 Quantity in Stock: 50
8 Zoom in and configure
If this is the case you can use the following code. It assumes your data is in A1 to D8 in Sheet 1.
Sub FormatData()
Dim col As Integer
For col = 1 To 4
With Worksheets(2)
.Cells(1, col) = Cells(1, col) //Get name
.Cells(2, col) = Cells(2, col) & "; " & Cells(3, col) & "; " & Cells(4, col) & "; " & Cells(5, col) //Concatenate descriptions into single string
.Cells(3, col) = Cells(7, col) //Get quantity in stock
End With
Next col
End Sub