Testing ActiveCell with Index Match, results always True - excel

first of all, thank you all, your questions and answers have been of great value over the years, but now i've run into a problem of which I'm just not seeing/finding the solution.
Edit: before i even asked the question: solved big part of my question already, but now i have 1 issue remaining. I'll leave the details below in, just for clarity.
Document layout:
Sheet1: Overview (gets renewed every week or so, on command).
Contains array of (text) data A:Z, approx 3k lines.
Column A contains the unique identifier, for the contents of said row.
Sheet2: Backup (contains exact backup, pre-update of Overview)
Goal:
Loop through all unique identifiers (Col.A) and test B:Z with respect to B:Z on Sheet2, the backup, with an INDEX/MATCH. If the value of the backup is different, add that value as a Note(comment) to the ActiveCell.
Created a small testworkbook, with the following data on Sheet1 -and- Sheet2:
Unique
V1
V2
V3
V4
212223
B
C
D
E
212224
F
G
H
I
212238
J*
K
L
M
*Cell B4 on Sheet1 was updated to "Z".
Now i got pretty much everything working, except my comparing the ActiveCell offset to the Index/Match result. I'm looping through my range in Col A, checking each following column for it's matching value on Sheet2. When i arrive at the following point in the code, my activecell is A2. Condensed down, looks like this:
Sub CellCheck()
Dim NewNote As Variant 'Note-Content to be
Dim ActiveCell_Debug As Variant
Dim col As Integer 'Starting Column Counter
col = 1
'Start at cell A2
ActiveCell_Debug = ActiveCell.Address
If ActiveCell.Offset(0, col).Value <> "INDEX(Sheet2!$B:$B, MATCH(Sheet1!" & ActiveCell_Debug & ",Sheet2!A:A,0))" Then
NewNote = Application.Evaluate("INDEX(Sheet2!$B:$B, MATCH(Sheet1!" & ActiveCell_Debug & ",Sheet2!A:A,0))")
ActiveCell.Offset(0, col).AddComment
ActiveCell.Offset(0, col).Comment.Text Text:=NewComment
'ActiveCell.Offset(0, col).DisplayCommentIndicator = -1
End If
End Sub
Now "ActiveCell.Offset(0, col).Value" is "B".
And "INDEX(Sheet2!$B:$B, MATCH(Sheet1!" & ActiveCell_Debug & ",Sheet2!A:A,0))" is -also- "B".
But 'NewNote' is now also "B".
If i make Cell A4 the Activecell, result is "J" as expected. So, no matter what the test is always true.
What am i missing here?
Many thanks in advance.

Related

Replicating values

Need a little help here.
In the "Data" Tab I want to copy values in column "c2:c1000" and paste in column "a1" of another Tab.
This is what i have so far,
Dim x As Long
Dim lastRow As Long
lastRow = Worksheet("Data").Cells(3, Columns.Count).End(xlUp).Column
For x = 1 To lastRow
If Worksheets("Sheet2").Cells(2, "A") = "" Then
Worksheets("Data").Range("c2:c1000").Copy Destination:=Worksheets("Sheet2").Range(1, "A")
Sheets("Sheet2").Range("A1").Value = Format(Now, "mm/dd/yyyy HH:mm:ss")
Else
Worksheets("Data").Range("c2:c1000").Copy Destination:=Worksheets("Sheet2").Cells(2,
Columns.Count).End(xlToLeft).Offset(, 1)
'Sheets("Sheet2").Range("A1").Value = Format(Now, "mm/dd/yyyy HH:mm:ss") --> can't figure how to increment this as this will need to be on the subsequent empty column
End If
Next
End Sub
Your help will be greatly appreciated!
Thank you.
Pasting values first into range A1 and down and then next time to cell B1 and so on, leaves no space for the timestamp to A1, B1 etc. So, I assume that you would like to paste the random values to row 2. So cells A1, B1, ... are left for the timestamp.
Inside the With statements we can refer to properties of the wsAudit so we can replace the "Worksheets("Audit")." reference with just "."
The column.count expression just checks the amount of columns in the worksheet.
The expression .Cells(2, Columns.Count) just points to last cell in the row 2.
The .End(xlToLeft).Column then looks from this column to left and is supposed to find the last not empty cell on this row. It's basically the same idea that in Excel's sheet you would go to cell XDF2 and hit CTRL+Arrow Left from keyboard.
But instead of activating the cell we just want to get the columns index number and then add 1 (the new column) and save it into variable. Now the new column is known.
The expression Range(.Cells(2, newColAudit), .Cells(1000, newColAudit)).Value is really the same as e.g. Range("B2:B1000"), but with this we can use the row and column index numbers instead. This is useful as the column number varies.
And as Samuel pointed out the copy paste operation can be avoided by setting the areas equal.
Dim wsAudit As Worksheet
Dim newColAudit As Long
Set wsAudit = Worksheets("Audit")
With wsAudit
newColAudit = .Cells(2, Columns.Count).End(xlToLeft).Column + 1
Range(.Cells(2, newColAudit), .Cells(1000, newColAudit)).Value = Worksheets("Data").Range("C2:C1000").Value
.Cells(1, newColAudit).Value = Format(Now, "mm/dd/yyyy HH:mm:ss")
End With
Much like your LastRow* variable for your source sheet, create a LastColumn variable for your destination sheet, which will find the last used column the same way you are finding your last used row.
Like so:
Dim LastColumn As Long
LastColumn = Sheets("Audit").Cells(1, Columns.Count).End(xlToLeft).Column
Then use the variable like so:
Destination:= Worksheets("Audit").Cells(1, LastColumn)
It seems that your code contradicts your question too, in your question you explained the data will be written to the Audit sheet in row 1, using the next column each time but your code looks for values in row 2 in your If statement:
If Worksheets("Audit").Cells(2, "A") = "" Then is the same as If Worksheets("Audit").Range("A2") = "" Then.
If you mean to check the first row, change the 2 to 1.
To help improve your codes efficiency:
(Also see the link to 'how to avoid select' in that question):
You can achieve 'copy/paste' without actually using the 'copy' and 'paste' methods by assigning the value of one range to the other, as example, like so:
Worksheets("Audit").Cells(1, LastColumn).Resize(999, 1) = Worksheets("Data").Range("c2:c1000").Value
Note: Change the Resize Property rows to suit the source range (in this case you are wanting to move values from C2:C1000).
*The LastRow variable is a bit confusing, as it is looking for the last used column in row 3.
If it's meant to find a column, consider renaming it to avoid confusion later on in debugging.
If it's meant to find the last row, try like this:
LastRow = Worksheet("Data").Cells(Rows.Count, 1).End(xlUp).Row

Excel Automated Data Retrieval From Another Workbook

So I'm pretty new to excel formulas and got almost no experience with VBA. But I've come across with a problem that I need to solve.
So the scenario goes like this.
I've got two workbooks and I need to retrieve data to one workbook from another if the condition for a cell value is met. Let me explain with an example.
(C for columns, R for rows, x for random numbers)
I've got Workbook A as shown below:
And Workbook B with the same structure
So what I'm trying to achieve here is:
When I change/insert values in Workbook A, C3Rx there will be a conditional mechanism that will check for the value.
Let's say if C3R1's value is "1" on Workbook A, it should fill C1R1, C2R1 and C3R1 on Workbook B accordingly.
If the value is not "1", it just should keep scanning the Workbook A, C3 and when it meets the conditional requirement (C3Rx having the value of "1"), it should write it in and go to the next row (C1R(x+1)). Follow the procedure again and again. Scanning all values in Workbook A.
I've tried to make it work using VLOOKUP and some other functions together but it doesn't suit really well with my case. It works with spaces when the value does not meet the condition and also, I need to fill all the cells on C1 with the formula till the end. (considering I don't know how long it may go, that's not really a solution for me)
I think it's achievable with Macros but like I've said, I don't have much experience with VBA.
Thanks for your help in advance.
Have a good one.
I'm not exactly get what you mean.
Anyway below I am guessing on what you mean.
Below is what contains in Workbook-A sheet1 column A to C
Below is what contains in Workbook-B sheet1 column A to C
With the first condition that Workbook-A and Workbook-B are arlready open.... below is Workbook-A sheet1 where cell C4 and C7 fill with 1 value,
and after the button is clicked :
1. Cell A4 to C4 value in Workbook-A Sheet1 become the value of cell A4 to C4 value in Workbook-B Sheet1.
2. Cell A7 to C7 value in Workbook-A Sheet1 become the value of cell A7 to C7 value in Workbook-B Sheet1
Button1 is assign to a macro like this :
Sub test()
Set wbA = Workbooks("Test-A.xlsm").Sheets("Sheet1")
Set wbB = Workbooks("Test-B.xlsm").Sheets("Sheet1")
Set Rng = wbA.Range("C2", Range("C2").End(xlDown))
For Each cell In Rng
If cell.Value = 1 Then
r = cell.Row
wbA.Range("A" & r, "C" & r).Value = wbB.Range("A" & r, "C" & r).Value
'wbA.Range("A" & r, "C" & r).Interior.Color = vbRed
End If
Next
End Sub
The code will look to each value in column C (starts from row 2) in Workbook-A sheet1.
If the code find the value is 1 in row X of column C, then it copy row X of column A to C in Workbook-B sheet1.
That's if I'm not mistaken on what you mean.
Assumed that both workbooks already open.
Below is the beginning look of wb-A right after it's open :
Below is the beginning look of wb-B right after it's open :
Back to wb-A, after you examined the data, you decided that id-003 branch location is not London, but Madrid. So you type number 1 in the third column id-003 row. WB-A now look like this :
And what you expect is, if the code find any row in the third column of wb-A with value "1", then the code have to copy all the three columns of id-003 row then paste it to the last blank row in the emp_id column of wb-B. So, wb-B look like this :
Here is the code which has to be in wb-A module :
Sub test()
Set wbA = Workbooks("Test-A.xlsm").Sheets("Sheet1")
Set wbB = Workbooks("Test-B.xlsm").Sheets("Sheet1")
Set Rng = wbA.Range("C2", Range("C2").End(xlDown))
For Each cell In Rng
If cell.Value = 1 Then
Range(cell, cell.Offset(0, -2)).Copy Destination:= _
wbB.Range("A1000000").End(xlUp).Offset(1, 0)
End If
Next
End Sub
Again, above is just my guessing because I'm still not clear what you want and how is the situation.

Cut and paste using an offset

I am building a web scraping tool that obtains particular data. Once the data has been extracted the next step is to summarize it into a report thus i need some guidance on the final part of the project.
I have a column (Column A) that contains the following data set
Description of product
$3000
Description of product
$5000
etc
I would like to find a value (in this case the common value is $) and cut this value next to the description (into Column B). There could be hundreds of rows thus a loop would be required.
My initial thought is to use code that will find a value ($), then once the value is found, cut the row and using an offset paste the value (into column B)
Any help would be appreciated
sub test()
dim usedrows,i as integer
usedrows = activesheet.range("A" & activesheet.rows.count).end(xlup).row
for i=0 to usedrows
if instr(range("A" & i+1),"$") <> 0 then
'Checks if the looped cell has "$" sign
range("B" & i+1)=range("A" & i+1)
range("A" & i+1)=""
end if
next
end sub
Copy ColumnA into ColumB. Delete B1 with Shift cells up. Series fil1 a column with 1 in odd rows, 2 in even, then filter to select the 2s delete those rows and then the column of 1s.

Incremental Numbering while skipping over certain cells

I am trying to do an incremental numbering in Excel, but for a specific condition. If the condition does not match, then it should keep the existing cell details.
Image:
As you can see from the picture, I want to create a numbering list in column B, which is based off information shown in the corresponding row in column D. So on the second row, I would the counting to start at "1" and then continue to expand only as the count of "is_null" and "equal" grows. At the same time, I want it to skip over the green and blue cells and keep the contents as is.
As of right now, I have done the following formula:
=COUNTIF($D$1:D2,"is_null")+COUNTIF($D$1:D2,"equals")
This does the proper numbering, however it over-writes the green and blue cells instead of keeping them as "A" and "stop" respectively.
If someone can help me with that issue, then I should be good to go. Thanks!
I'm not sure what the value should be if in Column D you find the String "set_path" or "stop", but if these are always the same (i.e. "a" if Column D = "set_path" and "stop" if Column D = "stop"), you could achieve your desired results with the following formula:
=IF(AND(D2<>"set_path",D2<>"stop"),COUNTIF($D$1:D2,"is_null")+COUNTIF($D$1:D2,"equals"),IF(D2="set_path","a",IF(D2="stop","stop","")))
UPDATE:
Using VBA you could leave the contents of the cell as they are without overwriting them with a formula using the code below:
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set the worksheet you are working with, amend as required.
Dim LastRow As Long, i As Long
LastRow = ws.Cells(ws.Rows.Count, "D").End(xlUp).Row
'get the last row with data on Column D
For i = 2 To LastRow
If ws.Cells(i, "B").Value = "" Then 'if cell is empty add formula
ws.Cells(i, "B").FormulaR1C1 = "=COUNTIF(R1C4:RC[2],""is_null"")+COUNTIF(R1C4:RC[2],""equals"")"
End If
Next i
End Sub
Second Update:
I've now adapted the formula to increment the letters by one if "set_path" is found in Column D (Please bear in mind that this will go from A-Z and then it will start going through symbols as per ASCII table, so you might have to amend this if you want alternate behavior):
=IF(AND(D2<>"set_path",D2<>"stop"),COUNTIF($D$1:D2,"is_null")+COUNTIF($D$1:D2,"equals"),IF(D2="set_path",IFERROR(CHAR(COUNTIF($D$2:D2,"set_path")+64),""),IF(D2="stop","stop","")))

Loop through each cell in a column, compare each cell to a list and enter an associated description into an adjacent cell

Objective: loop through a column of Numbers/Codes and match these Codes to their descriptions (in a list) and populate the cell in the next column with the associated description. For example: A2=123456, A3=885467, A4=954789 and so on... Read in the first cell, A2 (123456). Find 123456 in the list (123456 = Finance), place "Finance" in B2. Read in 885467 (A3). Find (885467 = Marketing) in the list, place "Marketing" in B3... and so on. The closest I've come to solving this is:
Sub JobCodeDescription()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
'There are 3 worksheets in this Workbook.
'Job Code
'Location Code
'Entity Code
'Dim x As Number
Dim f As Range
For Each f In ActiveSheet.UsedRange.Columns("F").Cells
If f = "00053" Then ActiveCell.Offset(0, 1).Value = "Finance"
ElseIf f = "00056" Then ActiveCell.Offset(0, 1).Value = "Marketing"
ElseIf f = "00082" Then ActiveCell.Offset(0, 1).Value = "Technology"
' continues on...
Next f
' This works but the Active Cell DOES NOT move with "f". So the same cell continues to be populated and overwritten.
Next ws
End Sub
These Codes never come to me in any specific order and there WILL be duplicates, so I've tried sorting in ascending order. That seems to help, but I just can't figure out the looping through the Job Codes, and looping through the list to find the matching Code description. I might be going about this all wrong. I'd like to just compare the codes in column A to a flat-file but I don't know how to do that. The "Flat-File" is just a .txt file and it is a list of the Job Codes and their descriptions. Example: 123456 = Finance.
Any help would be greatly appreciated.
From your description, if I understand it correctly, I think you'd be better off with Vlookup(), since it's a built-in function and doesn't require macros.
If your data table is in J1:K4, and your list of accounts is in A1:A4, you can use the following formula in B1, and copy down:
=VLOOKUP(A1,$J$1:$K$4,2,FALSE)
This will search the range J1:J4 for the value in A1, then return the matching value in column K:
But, if you want to use your macro, #ThomasInzina is correct, you need to use f.Offset(...) instead of ActiveCell.Offset(...).

Resources