0

I am trying to build a macro that loops through a range of values within colA and check if they exist with another workbook. In one of them I would like to mark it "Worked"/"Not Worked"

Image Any guidance on where to start?

Community
  • 1
  • 1
user1810449
  • 173
  • 4
  • 5
  • 19
  • you can do this by, open one workbook(named book1) and store its value in Dictionary. Then access one by one value from another workbook(name book2) and check for existence of that word in Dictionary. If match found then mark that word in book2. Hope it will help you. For anymore query kindly make me know. – Pallav Raj Feb 12 '14 at 11:03

2 Answers2

1

Example

Here is an example of what you're looking for. Remember that both the workbooks have to be opened in the same instance of Excel.

Sub check()

Dim i As Integer, k As Integer, j As Integer 'Define your counting variables
Dim Report1 As Worksheet, bReport As Workbook, Report2 As Worksheet, bReport2 As Workbook 'Define your workbook/worksheet variables

Set Report1 = Excel.ActiveSheet 'Assign active worksheet to report1
Set bReport = Report1.Parent 'Assign the workbook of report 1 to breport


On Error GoTo wbNotOpen 'If an error occurs while accessing the named workbook, send to the "wbNotOpen" line.
Set bReport2 = Excel.Workbooks("otherworkbookname.xlsm") 'Assign the other workbook which you are cross-referencing to the bReport2 variable.
Set Report2 = bReport2.Worksheets("otherworksheetname") 'Do the same with the worksheet.
On Error GoTo 0 'Reset the error handler (to undo the wbNotOpen line.)

k = Report1.UsedRange.Rows.Count 'Get the last used row of the first worksheet.
j = Report2.UsedRange.Rows.Count 'Get the last used row of the second worksheet.

For i = 2 To k 'Loop through the used rows of the first worksheet. I started at "2" to omit the header.
    'Next, I used the worksheet function "countIf" to quickly check if the value exists in the given range. This way we don't have to loop through the second worksheet each time.
    If Application.WorksheetFunction.CountIf(Report2.Range(Report2.Cells(2, 1), Report2.Cells(j, 1)), Report1.Cells(i, 1).Value) > 0 Then
        Report1.Cells(i, 5).Value = "Worked" 'If the value was found, enter "Worked" into column 5.
    Else
        Report1.Cells(i, 5).Value = "Not worked" 'If the value wasn't found, enter "Not worked" into column 5.
    End If
Next i




Exit Sub
'This is triggered in the event of an error while access the "other workbook".
wbNotOpen:
MsgBox ("Workbook not open. Please open all workbooks then try again.")
Exit Sub

End Sub

This link also includes steps that tell how to check if a cell exists in another workbook. The comments are useful.

Community
  • 1
  • 1
Ross Brasseaux
  • 3,879
  • 1
  • 28
  • 48
  • The following code I am trying to make sense of { If Application.WorksheetFunction.CountIf(Report2.Range(Report2.Cells(2, 1), Report2.Cells(j, 1)), Report1.Cells(i, 1).Value) > 0 Then } If you can explain how the referencing is working, I semi-understand it. – user1810449 Feb 16 '14 at 12:09
  • I ask the above because I have made the necessary changes and tried running the macro using some test data that exists in both documents however all it displays is "Not Worked" – user1810449 Feb 16 '14 at 12:28
  • @user1810449 That line is basically the VBA version of the CountIf function in excel. It works the same way; it uses two parameters: one for the range and one for the search value. The only difference is you have to specify the range using VBA `mySheet.Range(cellone,celltwo)`. In the code above, cell one is `Report2.Cells(2,1)` and cell two is `Report2.Cells(j,1)`. The search value is `Report1.Cells(i,1).Value`. You want the `.Value` there because we are referencing the contents of the cell and not the cell itself. – Ross Brasseaux Feb 17 '14 at 14:35
0

Thanks to #Lopsided's solution, I have tweeked his code to bring forth this solution. And this seems to work.

{       
Sub CheckValue()

Dim S1 As Worksheet
Dim S2 As Worksheet

Dim i As Integer
Dim k As Integer
Dim j As Integer

Set S1 = Worksheets("Sheet1")
Set S2 = Worksheets("Sheet2")

k = S1.UsedRange.Rows.Count
j = S2.UsedRange.Rows.Count

For i = 1 To k
If Application.WorksheetFunction.CountIf(S2.Range(S2.Cells(2, 1), S2.Cells(j, 1)), S1.Cells(i, 1).Value) > 0 Then
    S1.Cells(i, 5).Value = "Worked" 'If the value was found, enter "Worked" into column 5.
Else
    S1.Cells(i, 5).Value = "Not worked" 'If the value wasn't found, enter "Not worked" into column 5.
End If
Next i
End Sub

}

user1810449
  • 173
  • 4
  • 5
  • 19
  • I would like to know if there is a quick resolve for this blanks cells get marked. Whenever I run the macro it marks it as desired, however it also marks the blanks cells also. – user1810449 Feb 16 '14 at 17:52
  • If you have blank cells within the used range of the first sheet, the countif function will use the empty string value as the search value. If you want to quickly omit these cells, just wrap the if function in another if. Like `If S1.Cells(i,1).Value <> "" Then`. Which basically says do the following only if the search value isn't blank. – Ross Brasseaux Feb 17 '14 at 14:42
  • Does that mean I have to write a nested if statement? Or just add another if then line below. – user1810449 Feb 17 '14 at 15:23
  • Nested. Put the line I wrote above it, and the `End If` line below. – Ross Brasseaux Feb 17 '14 at 15:46
  • I have added the if statement to the code and no matter what it displays "Not Worked" for all cells {For i = 2 To k If S1.Cells(i, 1).Value <> "" Then If Application.WorksheetFunction.CountIf(S2.Range(S2.Cells(2, 1), S2.Cells(j, 1)), S1.Cells(i, 2).Value) > 0 Then S1.Cells(i, 5).Value = "Worked" S1.Cells(i, 5).Interior.ColorIndex = 43 Else S1.Cells(i, 5).Value = "Not worked" S1.Cells(i, 5).Interior.ColorIndex = 36 'If the value wasn't found, enter "Not worked" into column 5. End If End If Next i} – user1810449 Feb 17 '14 at 20:58
  • Well my solution would only fix it if that was indeed the problem. It could be another issue. It might be best to just make another question. – Ross Brasseaux Feb 17 '14 at 21:16