VBA-Compare sheets and copy values from second sheet - excel

I am trying to compare two workbooks and copy the 5th column to the 5th column first workbook if the first 3 columns match.
This check has to be done throughout the worksheet.
Worksheet 1:
| Heading 1 | Heading2 | Heading 3 | Total | Number1 |
|-----------|----------|-----------|-------|---------|
| ABC | EF | GH | | |
| XYZ | AB | EF | | |
| HIK | IJ | PQ | | |
Worksheet 2:
| Heading 1 | Heading2 | Heading 3 | Total | Number1 |
|-----------|----------|-----------|-------|---------|
| QRS | EF | GH | | 5 |
| XYZ | AB | EF | | 4 |
| DEF | QR | IV | | 16 |
| HIK | IJ | PQ | | 8 |
Desired output:
| Heading 1 | Heading2 | Heading 3 | Total | Number1 |
|-----------|----------|-----------|-------|---------|
| ABC | EF | GH | | |
| XYZ | AB | EF | | 4 |
| HIK | IJ | PQ | | 8 |
I tried to do the following, but it didn't work:
Dim i As Integer
Sheets("Sheet1").Activate
For i = 2 To 100
ActiveSheet.Cells(i,5).Select
ActiveCell.FormulaR1C1 = "=IFERROR(IF(AND(Table2[#[Heading1]]=Consolidated!RC[-4],Table2[#[Heading2]]=Consolidated!RC[-3],Table2[#[Heading3]]=Consolidated!RC[-2]),Table2[Number1],"" ""),"" "")"
Next i
I am a VBA novice and would be grateful for any help.

You can do this with formulas, no need for code. I'll assume that "Heading 1" is in cell A1 for this: Add a new column between heading 3 and Total. In the first cell add the formula =A2&B2&c2 and copy down. Do the same in the other workbook. Now in Number1 in the first book enter this formula
=IFERROR(OFFSET([OtherWorkbook]SheetName!D2,MATCH(D2,[OtherWorkbook]Sheetname!D2:D5),2),"")
(Using your workbook and sheet names. Now copy down. You can then hide the column we added at the start by setting its width to zero in both books.

Related

Count adyacent non-blank cells in Excel/Google Sheets

I have an Excel/Google Sheets table in which some rows contain blank cells in between non-blank cells. I would like to count from left to right. I have used the formula COUNTA(A2:F2) but it cannot achieve what I want. This is a sample of the outcome I would like to get, with the Personalized count that I am seeking to achieve and the classic COUNTA:
I think that the task is slightly different from what you describe in the question, you want to count until blank and not between not blank cells.
So I made this working example
+---+------+------+------+------+------+------+-------+
| | A | B | C | D | E | F | G |
+---+------+------+------+------+------+------+-------+
| 1 | 2021 | 2020 | 2019 | 2018 | 2017 | 2016 | Count |
| 2 | 1 | 1 | 1 | 1 | 1 | 1 | 6 |
| 3 | 1 | 1 | 1 | 1 | | | 4 |
| 4 | 1 | | 1 | 1 | 1 | 1 | 1 |
| 5 | 1 | 1 | 1 | | | 1 | 3 |
+---+------+------+------+------+------+------+-------+
where cell G2 contains the following:
=IFERROR(MATCH(1;--(A2:F2="");0)-1;COUNTA(A2:F2))
is it right for you?

(VBA) Excel - How to transpose variable length columns to rows?

I have an Excel sheet with variable rows but 5 columns.
The final column has comma separated values of varying length.
I have been trying to write a "For Loop" to Transpose this data into Rows while retaining the Data in existing Columns A:D.
Source Data Sample
| User ID | User name | Group ID | Group name | Effective permissions | | | | | |
|---------|-----------|----------|------------|-----------------------|------|------|------|------|------|
| 1 | Adam | 100 | Active | ABCD | RFGE | ERTY | EDFR | | |
| 2 | Bryan | 100 | Bold | IFEU | WASD | WASF | TGRE | YMUN | TYBN |
| 3 | Charles | 100 | Charity | IFLL | ERTY | WSDF | XKLS | | |
| 4 | David | 100 | Danger | IFEU | UNBY | RVBT | ZXCV | XCVB | VBNM |
Output Data Example
| User ID | User name | Group ID | Group name | Effective permissions |
|---------|-----------|----------|------------|-----------------------|
| 1 | Adam | 100 | Active | ABCD |
| 1 | Adam | 100 | Active | RFGE |
| 1 | Adam | 100 | Active | ERTY |
| 1 | Adam | 100 | Active | EDFR |
| 2 | Bryan | 100 | Bold | IFEU |
| 2 | Bryan | 100 | Bold | WASD |
| 2 | Bryan | 100 | Bold | WASF |
| 2 | Bryan | 100 | Bold | TGRE |
| 2 | Bryan | 100 | Bold | YMUN |
| 2 | Bryan | 100 | Bold | TYBN |
| 3 | Charles | 100 | Charity | IFLL |
| 3 | Charles | 100 | Charity | ERTY |
| 3 | Charles | 100 | Charity | WSDF |
| 3 | Charles | 100 | Charity | XKLS |
| 4 | David | 100 | Danger | IFEU |
| 4 | David | 100 | Danger | UNBY |
| 4 | David | 100 | Danger | RVBT |
| 4 | David | 100 | Danger | ZXCV |
| 4 | David | 100 | Danger | XCVB |
| 4 | David | 100 | Danger | VBNM |
Any help you could provide would be greatly appreciated.
**I have completed VBA projects in the past, however I have usually been able to piece together previous examples to achieve my goal...learning along the way.
If someone could show me how to adapt the below code so that each of the values in my first 4 columns are copied down that would be great.
Sub Test()
Set Rng = Sheets("Test").Range("D2:D15")
Set Rng_output = Sheets("Test2").Range("A2")
For i = 1 To Rng.Cells.Count
Set rng_values = Range(Rng.Cells(i).Offset(0, 1), Rng.Cells(i).End(xlToRight))
If rng_values.Cells.Count < 16000 Then
For j = 1 To rng_values.Cells.Count
Rng_output.Value = Rng.Cells(i).Value
Rng_output.Offset(0, 1).Value = rng_values.Cells(j).Value
Set Rng_output = Rng_output.Offset(1, 0)
Next j
End If
Next i
End Sub
You are very close with that code.
Here is the same code, with a few small changes:
Sub Test()
Set Rng = Sheets("Test").Range("D2:D15")
Set Rng_output = Sheets("Test2").Range("A2")
For i = 1 To Rng.Cells.Count
'Test to make sure there is less than 16000 columns in this row past D. Yikes, OP!
Set rng_values = Range(Rng.Cells(i).Offset(0, 1), Rng.Cells(i).End(xlToRight))
If rng_values.Cells.Count < 16000 Then
'Loop through all of those columns
For j = 1 To rng_values.Cells.Count
'Write out value from Column A:D to our Rng_Output
Rng_Output.Value = rng.cells(i).Offset(0,-3).value 'Column A = Column A
Rng_Output.Offset(0,1).Value = rng.cells(i).Offset(0,-2).value 'Column B = Column B
Rng_Output.Offset(0,2).value = rng.cells(i).OFfset(0,-1).value 'etc..
Rng_Output.Offset(0,3).value = rng.cells(i).value
'Write out value from Column A:D to your `Test2` sheet column E
rng_output.Offset(0,1).Value = rng_values.Cells(j).value
'Increment to the next row
Set Rng_output = Rng_output.Offset(1)
Next j
End If
Next i
End Sub

excel to count the duplicate in a column

I need to find the duplicates in this way.please help me
--|-----|-------|-------|-------|-------
| A | B | C | D | E |
--|-----|-------|-------|-------|------|
1 | 1 | a1 | 1 | | |
2 | 2 | a2 | 1 | | |
3 | 3 | a3 | 1 | | |
4 | 4 | a5 | 1 | | |
5 | 5 | a1 | 2 | | |
6 | 6 | a2 | 2 | | |
7 | 7 | a1 | 3 | | |
8 | 8 | a3 | 2 | | |
9 | 9 | a1 | 4 | | |
10| 10 | a1 | 5 | | |
----------------------------------------
For ex: Individual duplicate B column- In B column "a1" - 5 duplicate values totally,
check the c column i need the output like that
You should be using this formula in Column C
=COUNTIF($B$1:$B1,B1)
Let me know if it does not work.
You want a cumulative sum of the number of occurences of the value in column B. You can do that by inserting the following formula in C2:
=COUNTIF("$A$2:A2; A2)
You then drag in vertically, as far as you like. The result should be something like this:
| "C"
2 | =COUNTIF("$A$2:A2; A2)
3 | =COUNTIF("$A$2:A3; A3)
4 | =COUNTIF("$A$2:A4; A4)
And so on, and so on...
In column C kindly enter below formula.
=COUNTIF($C$1:C1,C1)
And drag it to last cell c10
Regards
Lalit.M

Excel dynamic range in matrix

In my excel worksheet I have a matrix like this:
+---+------------+--------+--------+--------+--------+--------+-------+
| * | A | B | C | D | E | F | Col n |
+---+------------+--------+--------+--------+--------+--------+-------+
| 1 | 01/01/2000 | -1.000 | -1.000 | -1.000 | -1.000 | -1.000 | ... |
| 2 | 01/02/2000 | | 1.200 | 500 | 500 | 500 | ... |
| 3 | 01/03/2001 | | | 1.100 | 800 | 800 | ... |
| 4 | 01/04/2000 | | | | 1.000 | 700 | ... |
| 5 | 01/05/2000 | | | | | 900 | ... |
| 6 | 01/06/2000 | | | | | | ... |
| 7 | 01/07/2000 | | | | | | ... |
+---+------------+--------+--------+--------+--------+--------+-------+
I need a formula for each column (from column 2) with a dynamic range like this:
For Column B:
=XIRR(B1:B1,A1:A1)
For Column C:
=XIRR(C1:C2,A1:A2)
For Column D:
=XIRR(D1:D3,A1:A3)
For Column E:
=XIRR(E1:E4,A1:A4)
and so on.
Is it possible?
Thanks
I think what you are after is:
=XIRR(OFFSET(B$1,0,0,COLUMN()-1),OFFSET($A$1,0,0,COLUMN()-1))
Using OFFSET we can specify the number of rows in our offset range... We can use the COLUMN() number -1 to get 1 for B, 2 for C etc. We start the offset from an unfixed cell for the values (so it moves along the columns) and a fixed one for dates (so it stays in A)
This formula can just be copied along the cells as far as necessary...

How to get QTP and Excel to sort correctly?

I need to sort by columns a ascending, then b ascending, then d ascending and by columns e ascending, then f ascending, then h ascending. Using just QTP, I can't seem to get Excel to sort the data correctly.
What I want:
Table 1:
| a | b | c | d | e | f | g | h |
---------------------------------------------------------------------
| 1 | BE | blank | 51 stuff | 1 | BE | blank | 51 stuff |
| 1 | BE | blank | 100 stuff | 1 | BE | blank | 100 stuff |
| 1 | BE OF A | blank | 121 stuff | 1 | BE OF A | blank | 121 stuff |
| 1 | BE OF A | blank | 200 stuff | 1 | BE OF A | blank | 200 stuff |
| 2 | SEA | blank | 5 stuff | 1 | SEA | blank | 5 stuff |
What I got instead:
Table 2:
| a | b | c | d | e | f | g | h |
---------------------------------------------------------------------
| 1 | BE | blank | 100 stuff | 1 | BE OF A | blank | 121 stuff |
| 1 | BE | blank | 51 stuff | 1 | BE OF A | blank | 200 stuff |
| 1 | BE OF A | blank | 121 stuff | 1 | BE | blank | 100 stuff |
| 1 | BE OF A | blank | 200 stuff | 1 | BE | blank | 51 stuff |
| 2 | SEA | blank | 5 stuff | 1 | SEA | blank | 5 stuff |
Columns e through h gets populated and sorted first. Normally, the cells for those columns are populated in the correct sort order seen in Table 1. However, there have been instances where the sort order is incorrect, but that is rare. Maybe 1 out of 100,000 tries would it be populated with unsorted data.
Columns a through d gets populated and sorted last. The cells for those columns are populated in a somewhat haphazard manner. Table 3 illustrates a very simple end result without forcing a sort.
Table 3:
| a | b | c | d | e | f | g | h |
---------------------------------------------------------------------
| 1 | BE | blank | 100 stuff | 1 | BE | blank | 51 stuff |
| 1 | BE | blank | 51 stuff | 1 | BE | blank | 100 stuff |
| 1 | BE OF A | blank | 121 stuff | 1 | BE OF A | blank | 121 stuff |
| 1 | BE OF A | blank | 200 stuff | 1 | BE OF A | blank | 200 stuff |
| 2 | SEA | blank | 5 stuff | 1 | SEA | blank | 5 stuff |
What's the best way to get QTP and Excel to return the results displayed in Table 1? Is there even a way to?
Snippet of the code(s) that I'm using:
'Some Code Stuff here which leads to exporting the worksheet
rangeOne = "E1:H" & totalRowCnt
Set rangeObj = worksheetOne.Range(rangeOne)
Set range1 = excel1Obj.Range("E1")
Set range2 = excel1Obj.Range("F1")
Set range3 = excel1Obj.Range("H1")
rangeObj.Sort range1, ascend1, range2, ,ascend1, range3, ,ascend1,yes1
'Save worksheet then import sorted data back into Datatable
'and add more Code Stuff here which leads to exporting the worksheet again
rangeOne = "A1:D" & totalRowCnt
Set rangeObj = worksheetOne.Range(rangeOne)
Set range1 = excel1Obj.Range("A1")
Set range2 = excel1Obj.Range("B1")
Set range3 = excel1Obj.Range("D1")
rangeObj.Sort range1, ascend1, range2, ,ascend1, range3, ,ascend1,yes1
'Save worksheet then end script
Try loading the data into a Recordset object. You can sort the recordset like this:
rs.Sort = "a ASC, b ASC, d ASC, e ASC, f ASC, h ASC"
then copy the sorted data to Excel or write them to a CSV.
rs.MoveFirst
Do Until rs.EOF
For i = 0 To rs.Fields.Count - 1
'copy/write rs.Fields(i).Value
Next
rs.MoveNext
Loop

Resources