Looping through range using VBA in Excel - vba

I have a block of code that takes way too long to process for some files. Smaller files (fewer lines of data) work fine, but once I get to about 150-300, it starts to get slow, (sometimes I think the whole process actually just hangs) and I have to run this sometimes on files with up to 6,000.
I want to plug in a VLookup() function in the .FormulaR1C1 for a number of cells. I know that I can set the whole range at once using .Range("J2:J" & MaxRow). However, I am looping through a block of cells to check the value of those cells. IF they are empty, THEN I want to apply the formula. If those cells already have values, then I don't want to change them, so I don't think the whole range option will work for me (at least I was unable to get it right).
Private Sub PullMIAFinalizedData(NewMIARep As Worksheet, MaxRow As Long, wkbFinalized As Workbook)
Dim wksFinalized As Worksheet
Dim lCount As Long
Dim sVLookupJBlock As String
Dim sVLookupKBlock As String
Application.Calculation = xlCalculationManual
sVLookupJBlock = "=IF(ISERROR(" & _
"VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C13,13,FALSE))," & _
Chr(34) & Chr(34) & _
",VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C13,13,FALSE))"
sVLookupKBlock = "=IF(ISERROR(" & _
"VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C3,3,FALSE))," & _
Chr(34) & Chr(34) & _
",VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C3,3,FALSE))"
For Each wksFinalized In wkbFinalized.Sheets
ShowAllRecords wksFinalized 'Custom Function to unhide/unfilter all data
With NewMIARep
For lCount = 2 To MaxRow
If .Range("J" & lCount).value = "" And .Range("K" & lCount).value = "" Then
.Range("J" & lCount).FormulaR1C1 = sVLookupJBlock
.Range("K" & lCount).FormulaR1C1 = sVLookupKBlock
Application.Calculate
With .Range("J" & lCount & ":K" & lCount)
.value = .value
End With
End If
Next lCount
.Range("J2:J" & MaxRow).NumberFormat = "mm/dd/yyyy"
End With
Next wksFinalized
Application.Calculation = xlCalculationAutomatic
End Sub
Am I just stuck with this?

Thanks very much to assylias and Siddharth Rout for helping out with this; both provided very useful information, which led to this result:
Private Sub PullMIAFinalizedData(NewMIARep As Worksheet, MaxRow As Long, wkbFinalized As Workbook)
Dim wksFinalized As Worksheet
Dim lCount As Long
Dim lFinMaxRow As Long
Dim DataRange As Variant 'per assylias, using a variant array to run through cells
Dim FoundRange As Range
Application.Calculation = xlCalculationManual
With NewMIARep
DataRange = .Range("J2:K" & MaxRow)
For Each wksFinalized In wkbFinalized.Sheets
ShowAllRecords wksFinalized
lFinMaxRow = GetMaxRow(wksFinalized)
If lFinMaxRow > 1 Then
For lCount = 1 To MaxRow - 1
If Len(DataRange(lCount, 1)) = 0 And Len(DataRange(lCount, 2)) = 0 Then
'per Siddharth Rout, using Find instead of VLookup
Set FoundRange = wksFinalized.Range("A2:A" & lFinMaxRow).Find(What:=.Range("A" & lCount).value, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Not FoundRange Is Nothing Then
DataRange(lCount, 1) = FoundRange.Offset(ColumnOffset:=12).value
DataRange(lCount, 2) = FoundRange.Offset(ColumnOffset:=2).value
Set FoundRange = Nothing
End If
End If
Next lCount
End If
Next wksFinalized
.Range("J2:K" & MaxRow).value = DataRange
.Range("J2:J" & MaxRow).NumberFormat = "mm/dd/yyyy"
End With
Application.Calculation = xlCalculationAutomatic
End Sub

You don't want to iterate on cells from VBA: it is EXTREMELY slow. Instead, you put the data you need into an array, work on the array and put the data back to the sheet. In your case, something like the code below (not tested):
Dim data as Variant
Dim result as Variant
Dim i as Long
data = ActiveSheet.UsedRange
ReDim result(1 To UBound(data,1), 1 To UBound(data,2)) As Variant
For i = LBound(data,1) to UBound(data,1)
'do something here, for example
If data(i,1) = "" Then
result(i,1) = "=VLOOKUP($A1,$A:$G," & i & ",FALSE)"
Else
result(i,1) = data(i,1)
End If
Next i
ActiveSheet.Cells(1,1).Resize(Ubound(result, 1), UBound(result,2)) = result

Related

Conflicting DATA - Duplicated values

I created a macro that fills the missing Data with specific Data from another sheet , the codes works perfectly in copying pasting data from excel of the client and prepare the data needed to start the work but the only problem here below
Code:
With Worksheets("Feuil2")
' reference "target" sheet (change "Target" to our actual target sheet name)
With .Range("B1:B" & .Cells(.Rows.Count, 1).End(xlUp).Row) 'reference
its column B range from row 1 down to last not empty one
If WorksheetFunction.CountBlank(.Cells) > 0 Then
' if any blank cell in referenced range. this check to avoid error thrown by subsequent
statament
.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=index(GDC!" & rng.Offset(, 1).Address(, , xlR1C1) & ",match(RC[-1],GDC!" & rng.Address(, , xlR1C1) & ",0))" 'fill blank cells with a lookup (well, sort of) formula
.Value = .Value 'get rid of formulas and leave values only
Cells.Select
End If
End With
End With
This code works perfectly in matching and filling data but when for e.g find a duplicated value it copy only the first value not the second one
See the image below to better understand the main problem :
As you can see in the image The problem that in column A i may have data repeated twice like this value P20845 which in column F it is repeated one with the name of Ghaith and the other with the name of sirine but as you can see in the column A it is just with the name also of Ghaith and there is no name of sirine
Anyidea or better solution in solving this and getting all the needed DATA? .
Best Regards
POLOS
Or use a dictionary
Option Explicit
Public Sub AddValues()
Application.ScreenUpdating = False
Dim wb As Workbook, wsSource As Worksheet, wsTarget As Worksheet, masterDict As Object, arr() As Variant, i As Long, rng As Range
Set wb = ThisWorkbook
Set wsSource = wb.Worksheets("Feuil1")
Set wsTarget = wb.Worksheets("Feuil2")
Set masterDict = CreateObject("Scripting.Dictionary")
With wsSource
arr = Intersect(.Columns("A:B"), .UsedRange)
For i = 1 To UBound(arr, 1)
If Not masterDict.exists(arr(i, 1)) Then masterDict.Add arr(i, 1), GetAllMatches(arr(i, 1), arr(i, 2), wsSource)
Next i
End With
With wsTarget
For Each rng In Intersect(.Columns("A"), .UsedRange)
On Error Resume Next
rng.Offset(, 1) = masterDict(rng.Value)
On Error GoTo 0
Next rng
End With
Application.ScreenUpdating = True
End Sub
Public Function GetAllMatches(ByVal findString As String, ByVal dupString As String, ByVal searchRng As Worksheet) As String
Dim foundCell As Range
Dim concatenatedString As String
concatenatedString = vbNullString
With Intersect(searchRng.Columns(1), searchRng.UsedRange)
Set foundCell = .Find(findString)
If foundCell Is Nothing Then Exit Function
If Not foundCell Is Nothing Then concatenatedString = foundCell.Offset(, 1)
Dim currMatch As Long
currMatch = 0
For currMatch = 1 To WorksheetFunction.CountIf(.Cells, findString)
Set foundCell = .Find(What:=findString, After:=foundCell, _
LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not foundCell Is Nothing And InStr(1, dupString, concatenatedString) = 0 Then
concatenatedString = concatenatedString & "/" & foundCell.Offset(, 1)
Else
concatenatedString = foundCell.Offset(, 1)
End If
Next currMatch
End With
GetAllMatches = concatenatedString
End Function
Output in Feuil2
Maybe something like this instead?
Sub Test()
Dim i As Long, myrow As Long, lastrow As Long
Dim sht1 As Worksheet, sht2 As Worksheet
Set sht1 = ThisWorkbook.Worksheets("Sheet1")
Set sht2 = ThisWorkbook.Worksheets("Sheet2")
lastrow = 1
For i = 1 To 7
If Application.WorksheetFunction.CountIf(sht1.Range("A:A"), sht2.Range("F" & i).Value) = 0 Then
If i = 1 Then
lastrow = 1
Else
lastrow = sht1.Cells(sht1.Rows.Count, "A").End(xlUp).Row + 1
End If
sht1.Range("A" & lastrow).Value = sht2.Range("F" & i).Value
sht1.Range("B" & lastrow).Value = sht2.Range("G" & i).Value
Else
sht1.Range("B" & sht1.Columns("A:A").Find(What:=sht2.Range("F" & i).Value).Row).Value = sht1.Range("B" & sht1.Columns("A:A").Find(What:=sht2.Range("F" & i).Value).Row).Value & "/" & sht2.Range("G" & i).Value
End If
Next i
End Sub

Excel matching based on name date and copying data to another sheet

I have searched high and low and have tested many VB scripts but havent found a solution to this. the below is the data I have
Data
Need to have an output like below
result
the VB code I am using
Option Explicit
Public Sub PromptUserForInputDates()
Dim strStart As String, strEnd As String, strPromptMessage As String
'Prompt the user to input the start date
strStart = InputBox("Please enter the start date")
'Validate the input string
If Not IsDate(strStart) Then
strPromptMessage = "Oops! It looks like your entry is not a valid " & _
"date. Please retry with a valid date..."
MsgBox strPromptMessage
Exit Sub
End If
'Prompt the user to input the end date
strEnd = InputBox("Please enter the end date")
'Validate the input string
If Not IsDate(strStart) Then
strPromptMessage = "Oops! It looks like your entry is not a valid " & _
"date. Please retry with a valid date..."
MsgBox strPromptMessage
Exit Sub
End If
'Call the next subroutine, which will do produce the output workbook
Call CreateSubsetWorkbook(strStart, strEnd)
End Sub
'This subroutine creates the new workbook based on input from the prompts
Public Sub CreateSubsetWorkbook(StartDate As String, EndDate As String)
Dim wbkOutput As Workbook
Dim wksOutput As Worksheet, wks As Worksheet
Dim lngLastRow As Long, lngLastCol As Long, lngDateCol As Long
Dim rngFull As Range, rngResult As Range, rngTarget As Range
'Set references up-front
lngDateCol = 3 '<~ we know dates are in column C
Set wbkOutput = Workbooks.Add
'Loop through each worksheet
For Each wks In ThisWorkbook.Worksheets
With wks
'Create a new worksheet in the output workbook
Set wksOutput = wbkOutput.Sheets.Add
wksOutput.Name = wks.Name
'Create a destination range on the new worksheet that we
'will copy our filtered data to
Set rngTarget = wksOutput.Cells(1, 1)
'Identify the data range on this sheet for the autofilter step
'by finding the last row and the last column
lngLastRow = .Cells.Find(What:="*", LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
lngLastCol = .Cells.Find(What:="*", LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
Set rngFull = .Range(.Cells(1, 1), .Cells(lngLastRow, lngLastCol))
'Apply a filter to the full range to get only rows that
'are in between the input dates
With rngFull
.AutoFilter Field:=lngDateCol, _
Criteria1:=">=" & StartDate, _
Criteria2:="<=" & EndDate
'Copy only the visible cells and paste to the
'new worksheet in our output workbook
Set rngResult = rngFull.SpecialCells(xlCellTypeVisible)
rngResult.Copy Destination:=rngTarget
End With
'Clear the autofilter safely
.AutoFilterMode = False
If .FilterMode = True Then
.ShowAllData
End If
End With
Next wks
'Let the user know our macro has finished!
MsgBox "Data transferred!"
End Sub
but when data is like below the result doesnt show two rows with different time, any help would be much appreciated please.
Data 3
rgds
thanks for sharing your code. I think it looks a bit more than what you need. Going off your example, if everything is formatted as such, this would be your solution:
Option Explicit
Sub SplitDateTime()
Dim mydate As String, mytime As String, mytime2 As String, i As Long, sht As Worksheet, lastrow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
'Change headers
Range("H1:H" & lastrow).Value = Range("G1:G" & lastrow).Value
Range("G1:G" & lastrow).Value = Range("F1:F" & lastrow).Value
Range("D1").Value = "Date"
Range("E1").Value = "C/In"
Range("F1").Value = "C/Out"
'Move values around
For i = 2 To lastrow Step 2
mydate = DateValue(Range("D" & i).Value)
mytime = TimeValue(Range("D" & i).Value)
mytime2 = TimeValue(Range("D" & i + 1).Value)
Range("D" & i).Value = mydate
Range("E" & i).Value = mytime
Range("F" & i).Value = mytime2
Next i
'Delete excess rows
For i = lastrow To 2 Step -2
Range("A" & i).EntireRow.Delete
Next i
'Regrab lastrow value
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
'Change date format
Range("D2:D" & lastrow).NumberFormat = "m/d/yyyy"
End Sub

VBA-EXCEL Defining Ranges with variables

Problem: I am unable to define a range using a variable (i) and specific cells row (cell.Row).
Current Code:
Sub TaskSearch()
'Dim wb As Workbook
Dim oSht As Worksheet
Dim lastRow As Long, i As Long
Dim strSearch As String
Dim aCell As Range
ThisWorkbook.Sheets("Interface").Range("D19:D33").ClearContents
'Set wb = Workbooks.Open("H:\Kevin.Boots\Database.xlsx")
Set oSht = Sheets("TaskMaster")
lastRow = oSht.Range("A" & Rows.Count).End(xlUp).Row
strSearch = Sheets("Interface").Range("F5")
Set aCell = oSht.Range("B2:B" & lastRow).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
Sheets("Interface").Range("D19").Value = Sheets("TaskMaster").Range("C" & aCell.Row).Value
Sheets("Interface").Range("D20").Value = Sheets("TaskMaster").Range("D" & aCell.Row).Value
Sheets("Interface").Range("D21").Value = Sheets("TaskMaster").Range("E" & aCell.Row).Value
Sheets("Interface").Range("D22").Value = Sheets("TaskMaster").Range("F" & aCell.Row).Value
Sheets("Interface").Range("D23").Value = Sheets("TaskMaster").Range("G" & aCell.Row).Value
Sheets("Interface").Range("D24").Value = Sheets("TaskMaster").Range("H" & aCell.Row).Value
Sheets("Interface").Range("D25").Value = Sheets("TaskMaster").Range("I" & aCell.Row).Value
Sheets("Interface").Range("D26").Value = Sheets("TaskMaster").Range("J" & aCell.Row).Value
Sheets("Interface").Range("D27").Value = Sheets("TaskMaster").Range("K" & aCell.Row).Value
Sheets("Interface").Range("D28").Value = Sheets("TaskMaster").Range("L" & aCell.Row).Value
Sheets("Interface").Range("D29").Value = Sheets("TaskMaster").Range("M" & aCell.Row).Value
Sheets("Interface").Range("D30").Value = Sheets("TaskMaster").Range("N" & aCell.Row).Value
Sheets("Interface").Range("D31").Value = Sheets("TaskMaster").Range("O" & aCell.Row).Value
Sheets("Interface").Range("D32").Value = Sheets("TaskMaster").Range("P" & aCell.Row).Value
Sheets("Interface").Range("D33").Value = Sheets("TaskMaster").Range("Q" & aCell.Row).Value
Exit Sub
End Sub
Objective: I am attempting to make this code more robust. Part of reasoning is for me to be able to skip blanks. This is a nightmare when trying to adjust cells.
I have tried two different methods to accomplish this:
Method A:
wb.Sheets("Interface").Range("D19:D33").Copy
wb.Sheets("TaskMaster").Range("C" & aCell.Row & ":Q" & aCell.Row).PastSpecial Paste:=xlPasteValues, SkipBlanks:=True
Failure: Runtime Error 438: Object doesn't support this property or method.
Method B:
For j = 3 To 16
If Not IsEmpty(j, aCell.Row) Then
For i = 19 To 33
iWb.oSht.Range(j, aCell.Row).Value = _
iWb.iSht.Range(4, i).Value
Next i
End If
Next j
Exit Sub
Failure: ( I cant get this older version to compile again) I believe the error arose with issues defining the range.
To summarize I am trying to find the fastest method to transfer information from one worksheet to another worksheet using the .find. I am also trying to not copy blank cells while transferring.
I currently believe this method will be the best suited for my application.
Sub TSearch()
Dim dWb As Workbook, Wb As Workbook
Dim oSht As Worksheet, Sht As Worksheet
Dim lastRow As Long, i As Long, j As Long
Dim strSearch As String
Dim aCell As Variant
Dim cell As Variant
'On Error GoTo Err
ThisWorkbook.Sheets("Interface").Range("D19:D33").ClearContents
'Set dWb = Workbooks.Open("H:\Kevin.Boots\Database.xlsx")
Set Wb = ThisWorkbook
Set Sht = Sheets("TaskMaster") ' Reference Worksheet
Set oSht = Sheets("Interface") ' User Interface Worksheet
lastRow = Sht.Range("A" & Rows.Count).End(xlUp).Row 'Obtain Last row of reference Worksheet
strSearch = oSht.Range("F5") 'Obtain User Selected Search Criteria
Set aCell = Sht.Range("B2:B" & lastRow).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
For j = 3 To 16 'Columns from Reference Worksheet to be transfered
If Not IsEmpty(Wb.Sht.Cells(aCell.Row, j)) Then ' Verify If cell has value before transfering
For i = 19 To 33 ' Rows of User Interface where values are to be transfered
Wb.Sht.Cells(aCell.Row, j).Value = _
Wb.oSht.Cells(i, 4).Value
Next i
End If
Next j
Exit Sub
'Err: 'MsgBox " Generic Task not found" & vbCrLf
End Sub
The IEmpty Function is still causing an error 438: Object doesn't support this property method. If I remove the IsEmpty then
'Wb.Sht.Cells(aCell.Row, j).Value = Wb.oSht.Cells(i, 4).Value' gives me the same error.
Your loop won't work due to IsEmpty which expects a single cell or variable to check, but you are giving it two numbers. The below should work, but some things aren't qualified, so you may still run into issues. Also, Range() expects either two ranges to be provided, or a range string. I think you were looking for Cells(), which accepts a row (as a number) as the first parameter and a column (as a number) as the second.
For j = 3 To 16
If Not IsEmpty(cells(aCell.Row, j)) Then
For i = 19 To 33
iWb.oSht.Cells(aCell.Row, j).Value = _
iWb.iSht.Cells(4, i).Value
Next i
End If
Next j
End Sub
It appears the errors were a result of trying to define something that was defined.
Sub TSearch()
Dim dWb As Workbook, Wb As Workbook
Dim oSht As Worksheet, Sht As Worksheet
Dim lastRow As Long, i As Long, j As Long
Dim strSearch As String
Dim aCell As Variant
Dim cell As Variant
'On Error GoTo Err
ThisWorkbook.Sheets("Interface").Range("D19:D33").ClearContents
'Set dWb = Workbooks.Open("H:\Kevin.Boots\Database.xlsx")
Set Wb = ThisWorkbook
Set Sht = Sheets("TaskMaster") ' Reference Worksheet
Set oSht = Sheets("Interface") ' User Interface Worksheet
lastRow = Sht.Range("A" & Rows.Count).End(xlUp).Row 'Obtain Last row of reference Worksheet
strSearch = oSht.Range("F5") 'Obtain User Selected Search Criteria
'Find Row in Reference Worksheet that Matches Search Criteria
Set aCell = Sht.Range("B2:B" & lastRow).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
For j = 3 To 16
If Not IsEmpty(Cells(aCell.Row, j)) Then
i = j + 16
oSht.Cells(i, 4).Value = Cells(aCell.Row, j).Value
End If
Next j
Exit Sub
'Err:
'MsgBox " Generic Task not found" & vbCrLf
End Sub
Thank you to #Jordan and #Kyle for helping solve this issue.

VBA Loop to Highlight Inconsistencies

I have a spreadsheet with two columns (A and B). I would like to (FOR) loop through column B until two or more of the cell values match. For the cells that match in column B, I would like to loop through their corresponding values in column A. If their corresponding values are not identical, I want all of the rows involved to be highlighted.
I know it's not right/complete, but below is the basic structure I would like to follow. Any and all help is greatly appreciated. Thank you.
Sub MySUb()
Dim iRow As Integer
For iRow = 2 To ActiveSheet.UsedRange.Rows.Count
If Trim(range("A" & iRow)) <> "" And Trim(range("B" & iRow)) = Trim(range("B" & iRow)) Then
range("A" & iRow, "B" & iRow).Interior.ColorIndex = 6
End If
Next
End Sub
You can first sort based on Column B, then modify your code to:
Sub MySUb()
Dim iRow As Integer
For iRow = 1 To ActiveSheet.UsedRange.Rows.Count
If Trim(Range("A" & iRow).Text) <> "" And _
Trim(Range("B" & iRow).Text) = Trim(Range("B" & iRow + 1).Text) And _
Trim(Range("A" & iRow).Text) <> Trim(Range("A" & iRow + 1).Text) Then
Range("A" & iRow, "B" & iRow).Interior.ColorIndex = 6
Range("A" & iRow + 1, "B" & iRow + 1).Interior.ColorIndex = 6
End If
Next
End Sub
EDIT:
Here is a better solution which can handle the case where in column B there >2 matching cells, but the corresponding cells in A do not match (i.e. at least one of them is different). In this case all of those cells are marked.
Sub MySUb()
Dim iRow As Integer
Dim jRow As Integer
Dim kRow As Integer
For iRow = 1 To ActiveSheet.UsedRange.Rows.Count
'If Trim(Range("A" & iRow).Text) <> "" Then
For jRow = iRow To ActiveSheet.UsedRange.Rows.Count 'Finds the last non-matching item in B
If Trim(Range("B" & jRow).Text) <> Trim(Range("B" & iRow).Text) Then
Exit For
End If
Next jRow
For kRow = iRow To jRow - 1
If Trim(Range("A" & iRow).Text) <> Trim(Range("A" & kRow).Text) Then
Range("A" & iRow, "B" & kRow).Interior.ColorIndex = jRow + 1 'Or can be 6
End If
Next kRow
Next iRow
End Sub
How about something like this, using a dictionary to track the instances of an item in Column B and then testing the Column A values for each unique instance of Column B values. If one fails to match then all instances are marked.
Sub DuplicateChecker()
Dim rngColumnB As Range
Set rngColumnB = Range("B2", Range("B2").End(xlDown))
Dim rngCell As Range
Dim rngDupe As Range
Dim rngDuplicateB As Range
Dim dctValuesChecked As Dictionary
'requires enabled reference library for 'Microsoft Scripting Runtime'
Set dctValuesChecked = New Dictionary
Dim strColumnAValue As String
For Each rngCell In rngColumnB
strColumnAValue = rngCell.Offset(0, -1).Value
If Not dctValuesChecked.Exists(Trim(rngCell.Value)) Then
Call dctValuesChecked.Add(rngCell.Value, rngCell.Row)
Else
Set rngDuplicateB = FindItemsInRange(rngCell.Value, rngColumnB)
rngDuplicateB.EntireRow.Select
For Each rngDupe In rngDuplicateB
If Not rngDupe.Offset(0, -1).Value = strColumnAValue Then
rngDuplicateB.Interior.ColorIndex = 6
rngDuplicateB.Offset(0, -1).Interior.ColorIndex = 6
End If
Next rngDupe
End If
Next rngCell
End Sub
Function FindItemsInRange(varItemToFind As Variant, _
rngSearchIn As Range, _
Optional LookIn As XlFindLookIn = xlValues, _
Optional LookAt As XlLookAt = xlPart, _
Optional blnMatchCase As Boolean = False) As Range
'adapted from a function by Aaron Blood found on the Ozgrid forums:
'http://www.ozgrid.com/forum/showthread.php?t=27240
With rngSearchIn
Dim rngFoundItems As Range
Set rngFoundItems = .Find(What:=varItemToFind, _
LookIn:=LookIn, _
LookAt:=LookAt, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=blnMatchCase, _
SearchFormat:=False)
If Not rngFoundItems Is Nothing Then
Set FindItemsInRange = rngFoundItems
Dim strAddressOfFirstFoundItem As String
strAddressOfFirstFoundItem = rngFoundItems.Address
Do
Set FindItemsInRange = Union(FindItemsInRange, rngFoundItems)
Set rngFoundItems = .FindNext(rngFoundItems)
Loop While Not rngFoundItems Is Nothing And _
rngFoundItems.Address <> strAddressOfFirstFoundItem
End If
End With
End Function

how to get a % value after matching same name from 2 different worksheets

I was wondering if someone can help me solve the following problem. Someone has previously helped me on get the % of dctest/In value on the same worksheet. But right now, i need to do the same thing but on a different worksheet.
Say Sheet1
this is copied Sheet1 (1) after taking the %
Sub marco1()
'start making Sheet1 into %
'~~> Add/Remove the text here which you want to ignore
Excludetext = "In,test1,test2,test3,test4,test5,test6"
MyArray = Split(Excludetext, ",")
Set ws = Sheets("Sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
'Set Column B into %
For i = 1 To LastRow
boolContinue = True
For j = 0 To UBound(MyArray)
SearchText = UCase(Trim(MyArray(j)))
If UCase(Trim(ws.Range("A" & i).Value)) = SearchText Then
boolContinue = False
Exit For
End If
Next j
If boolContinue = True Then
With Range("B" & i)
.Formula = _
"=OFFSET(INDIRECT(ADDRESS(INDEX(MATCH(A" & i & _
",$A$1:$A$45,0),1,0),1,1,1,'Duplicated_Sheet1')),0,1)/$B$5"
.NumberFormat = "0.00%"
End With
End If
Next i
End sub
There is some error showing at the formula, did i make a mistake with the formula? Thank you in advance!
Is this what you are trying?
TRIED AND TESTED
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim wsData As String
Dim SearchText As String, Excludetext As String
Dim LastRow As Long, i As Long, j As Long
Dim MyArray() As String
Dim boolContinue As Boolean
'~~> Add/Remove the text here
Excludetext = "In,Test1,Test2,Test3,Test4,Test5,Test6"
'~~> Change this to the relevant sheetname which has the data
wsData = "Sheet1"
MyArray = Split(Excludetext, ",")
Set ws = Sheets("Sheet2")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To LastRow
boolContinue = True
For j = 0 To UBound(MyArray)
SearchText = MyArray(j)
If ws.Range("A" & i).Value = SearchText Then
boolContinue = False
Exit For
End If
Next j
If boolContinue = True Then
With ws.Range("B" & i)
.Formula = _
"=OFFSET(INDIRECT(ADDRESS(INDEX(MATCH(A" & i & _
"," & wsData & "!$A$1:$A$11,0),1,0),1,1,TRUE,""" & _
wsData & """)),0,1)/" & wsData & "!B1"
.NumberFormat = "0.00%"
End With
End If
Next i
End Sub
When using ADDRESS() for a cell in different sheet, you have to specify additional arguments.
Straight from Excel's help
Syntax of ADDRESS Function
ADDRESS(row_num, column_num, [abs_num], [a1], [sheet_text])
Where [sheet_text] is the name of the sheet which we are referring to. I would recommend reading more about it in Excel Help.
This is the actual formula for say dctest
=OFFSET(INDIRECT(ADDRESS(INDEX(MATCH(A7,Sheet1!$A$1:$A$11,0),1,0),1,1,TRUE,"Sheet1")),0,1)/Sheet1!B1
HTH
Sid