Scenario: -There are 2 sheets being compared. Range for Sheet1 is B2:B and for Sheet2 is C2:C.
Requirement:
Sheet1 B2 = Sheet2 C2
Sheet1 B3 = Sheet2 C3 and so on...
See my existing code below:
Sub MessageCode()
Dim FoundBlank1 As Range
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
Dim MyRange As Range, MyCell As Range, MyRange2 As Range, MyCell2 As Range
Set MyRange = ws.Range("B2:B" & ws.Range("B" & ws.Rows.Count).End(xlUp).Row)
Set MyRange2 = ws2.Range("C2:C" & ws2.Range("C" & ws2.Rows.Count).End(xlUp).Row)
Set MyCell2 = MyRange2
For Each MyCell In MyRange
If MyCell.Value <> Worksheets("Sheet2").Range("C2").Value Then
MyCell.Copy
Worksheets("Sheet3").Select
Set FoundBlank1 = Range("A1:A1000").Find(What:="", lookat:=xlWhole)
FoundBlank1.Select
Selection.PasteSpecial xlPasteValues
ActiveCell.Offset(0, 1).Value = "Incorrect Value."
End If
Next MyCell
End Sub
I've added in some extra message box if the number of rows of sheet 1 and 2 are not the same.
Try this:
Sub Messagecode()
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim lastrow1 As Integer
Dim lastrow2 As Integer
dim lastrow3 as integer
Dim i As Integer
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
ws1.Activate
lastrow1 = Cells(Rows.Count, 2).End(xlUp).Row
ws2.Activate
lastrow2 = Cells(Rows.Count, 3).End(xlUp).Row
If lastrow1 <> lastrow2 Then
MsgBox ("number of rows in Sheet1 is not equal to number of rows in Sheet2")
End If
For i = 2 To lastrow1
If ws1.Cells(i, 2) <> ws2.Cells(i, 3) Then
ws2.Cells(i, 3).Copy
Worksheets("Sheet3").Activate
lastrow3 = Cells(Rows.Count, 1).End(xlUp).Row
Cells(lastrow3, 1).Offset(1, 0).Activate
ActiveSheet.Paste
Cells(lastrow3, 1).Offset(1, 1) = "incorrect value"
End If
ws1.Activate
Next i
End Sub
You only need to set the last row for sheet1 and sheet3. run a loop from 2 to the lastrow and compare Sheet1.columnB with Sheet2.columnC if <> then copy the value in Sheet1 to Sheet3, offset 1 cell to the right and paste your text. You add +1 to the last row in Sheet3 so you don't keep writing over the same cell...
Dim i As Long
Dim lRow As Long
lRow = Sheet1.Cells(Rows.Count, "B").End(xlUp).Row
Dim lRow3 As Long
lRow3 = Sheet3.Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To lRow
If Sheet1.Cells(i, "B").Value <> Sheet2.Cells(i, "C").Value Then
Sheet3.Cells(lRow3, "A").Value = Sheet1.Cells(i, "B").Value
Sheet3.Cells(lRow3, "A").Offset(, 1).Value = "Incorrect Value."
End If
lRow3 = lRow3 + 1
Next i
Related
Looking to fill a variable range here. I can fill my formula to the right but when I want to fil it down, the formula disappears. I have also attached a picture and Column A starts with "Fund Name". Hope somebody can help me here thank you!! The link to the table is here. 1: https://i.stack.imgur.com/y1ZVH.png
Sub Six_Continue()
Dim Lastrow As Long
Dim lrow As Range
Dim Lastcol As Long
Dim lcol As Range
Lastrow = Cells(Rows.Count, 1).End(xlUp).Row
Set lrow = Range("C5:C" & Lastrow)
Lastcol = Cells(1, Columns.Count).End(xlToLeft).Column
Set lcol = Range("C3", Cells(3, Lastcol))
Range("C5").FormulaArray = "=IFERROR(INDEX(DataTable[[Period]:[Period]],SMALL(IF(DataTable[[LP ID]:[LP ID]]=C$2,IF(DataTable[[Fund ID]:[Fund ID]]=$B5,ROW(DataTable[[Fund ID]:[Fund ID]])-ROW(DataTable[[Fund ID]:[Fund ID]]))),1)),"" "")"
Range("C5", lcol.Offset(2)).FillRight
Range("C5", lcol.Offset(2)).FillDown
End Sub
The code below worked for me (with a much simplified array formula).
Sub Six_Continue()
' 25 Jan 2018
Dim Rng As Range
Dim LastRow As Long
Dim LastClm As Long
With ActiveSheet ' better specify by name
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
LastClm = .Cells(1, .Columns.Count).End(xlToLeft).Column
Cells(5, 3).FormulaArray = "=IFERROR(INDEX(DataTable[[Period]:[Period]],SMALL(IF(DataTable[[LP ID]:[LP ID]]=C$2,IF(DataTable[[Fund ID]:[Fund ID]]=$B5,ROW(DataTable[[Fund ID]:[Fund ID]])-ROW(DataTable[[Fund ID]:[Fund ID]]))),1)),"" "")"
' .Cells(5, 3).FormulaArray = "= $a1 * $k1:$k5 * C$1"
Set Rng = Range(.Cells(5, 3), .Cells(5, LastClm))
Rng.FillRight
Set Rng = Range(.Cells(5, 3), .Cells(LastRow, LastClm))
Rng.FillDown
End With
End Sub
I have two worksheets, "Signed" and "April".
I want to copy Column "Y" from "Signed" based on certain criteria into column "A" starting from the next available/blank row. ( so right under the existing data).
My criteria for column Y is that if column L = month of cell "D2" from "April" AND the year of cell "D2" from "ApriL"...( so right now D2 is 4/30/2017)..
then copy that cell in the next row of Col A of "April" and keep adding on.
my code is as follows:
Dim sourceSht As Worksheet
Dim myrange As Range
Dim DestRow As Integer
Dim ws2 As Worksheet
Dim MonthVal As String
Range("D3").Select
ActiveCell.FormulaR1C1 = "=MONTH(R[-1]C)"
Range("D3").Select
Selection.NumberFormat = "General"
MonthVal = ActiveCell.Value
Set sourceSht = ThisWorkbook.Worksheets("Signed")
Set myrange = sourceSht.Range("Y1", Range("Y" & Rows.Count).End(xlUp))
Set ws2 = Sheets("April")
DestRow = ws2.Cells(Rows.Count, "A").End(xlUp).Row + 1
For Each rw In myrange.Rows
If rw.Cells(12).Value = MonthVal Then
myrange.Value.Copy Destinations:=Sheets(ws2).Range("A" & DestRow)
End If
Next rw
Try this:
Dim sourceSht As Worksheet
Dim myrange As Range
Dim DestRow As Integer
Dim ws2 As Worksheet
Dim MonthVal As String
Dim rw As Range
Range("D3").Select
ActiveCell.FormulaR1C1 = "=MONTH(R[-1]C)"
Range("D3").Select
Selection.NumberFormat = "General"
MonthVal = ActiveCell.Value
Set sourceSht = ThisWorkbook.Worksheets("Signed")
Set myrange = sourceSht.Range("Y1:Y" & sourceSht.UsedRange.Row - 1 + sourceSht.UsedRange.Rows.Count)
Set ws2 = Sheets("April")
DestRow = ws2.Cells(Rows.Count, "A").End(xlUp).Row ' + 1
For Each rw In myrange '.Rows
If sourceSht.Cells(rw.Row, 12).Value = MonthVal Then
DestRow = DestRow + 1
rw.Copy Destination:=Sheets("April").Range("A" & DestRow)
End If
Next rw
Edit: fixed a potential loophole at line 15 (from Set myrange = sourceSht.Range("Y1:y" & sourceSht.UsedRange.Rows.Count) to Set myrange = sourceSht.Range("Y1:Y" & sourceSht.UsedRange.Row - 1 + sourceSht.UsedRange.Rows.Count)), in case there are unused rows at the top.
Trying to use vba to write countifs function but got an error of object doesn't support this property or method. (Run-time error 438)
Sub counters()
Dim rng, rng2, rng3, rng4 As Range
Dim lrow, lr, lr2, lr3, lr4 As Long
Dim ws, ws1 As Worksheet
Set ws = Sheets("Data")
Set ws1 = Sheets("Table E-1 Zip Codes PIF")
lr = ws.Cells(Cells.Rows.Count, "D").End(xlUp).Row
lr2 = ws.Cells(Cells.Rows.Count, "X").End(xlUp).Row
lr3 = ws.Cells(Cells.Rows.Count, "Y").End(xlUp).Row
lr4 = ws.Cells(Cells.Rows.Count, "AE").End(xlUp).Row
lrow = ws1.Cells(Cells.Rows.Count, "B").End(xlUp).Row
'zip code
Set rng = ws.Range("D2:D" & lr)
'county
Set rng2 = ws.Range("X2:X" & lr2)
'Region
Set rng3 = ws.Range("Y2:Y" & lr3)
'policy form
Set rng4 = ws.Range("AE2:AE" & lr4)
For i = 5 To lrow - 1
Worksheets("Table E-1 Zip Codes PIF").Cells(i, 4).Value = Application.WorksheetFunction.CountIfs(ws.rng, ws1.Cells(i, 2).Value, ws.rng2, ws1.Cells(i, 3).Value, ws.rng3, "NW", ws.rng4, "Basic Choice")
Next i
End Sub
Excel function works fine but need to use vba to automate the process. Tried recording the macro but it gives reference and wasn't sure how to re-write codes for ranges (ws.Range("x2:x" & lr)). All of the rng have the same amount of data (rows) so wasn't sure if I need to define it each time.
I want my result to be from D5 to N-1 in Table E-1... sheet. I used For i = 5 To lrow - 1 since there is a total in the last row.
In Table E-1 sheet, Column D have a list of zip codes and column E have a list of county that I am trying to match.
Except for how you use your CountIfs Function, since there are no screen-shots of your data, the code below will take care of your run-time errors.
Explanation for your run-time errors:
1.Wrong declaration, Dim ws, ws1 As Worksheet should be Dim ws As Worksheet, ws1 As Worksheet , otherwise ws is not defined as Worksheet. The same goes to all of your variables declarations.
2.Find last row in a column: lr = ws.Cells(Cells.Rows.Count, "D").End(xlUp).Row is wrong, it should be lr = ws.Cells(ws.Rows.Count, "D").End(xlUp).Row.
3.Like #Scott Holtzman wrote in his comment, since you already set your rng in previous lines, (Set rng = ws.Range("D2:D" & lr)) , then it should be used with just rng and not ws.rng.
4.To improve and clean your code, you could just use With ws in the beginning of your code, and nest most of it related objects underneath.
"Clean" Code
Option Explicit
Sub counters()
Dim rng As Range, rng2 As Range, rng3 As Range, rng4 As Range
Dim lrow As Long, lr As Long, lr2 As Long, lr3 As Long, lr4 As Long
Dim ws As Worksheet, ws1 As Worksheet
Set ws = Sheets("Data")
Set ws1 = Sheets("Table E-1 Zip Codes PIF")
' last row in Column B in "Table E-1 Zip Codes PIF" sheet
lrow = ws1.Cells(ws1.Rows.Count, "B").End(xlUp).Row
With ws
lr = .Cells(.Rows.Count, "D").End(xlUp).Row
lr2 = .Cells(.Rows.Count, "X").End(xlUp).Row
lr3 = .Cells(.Rows.Count, "Y").End(xlUp).Row
lr4 = .Cells(.Rows.Count, "AE").End(xlUp).Row
'zip code
Set rng = .Range("D2:D" & lr)
'county
Set rng2 = .Range("X2:X" & lr2)
'Region
Set rng3 = .Range("Y2:Y" & lr3)
'policy form
Set rng4 = .Range("AE2:AE" & lr4)
For i = 5 To lrow - 1
ws1.Cells(i, 4).Value = Application.WorksheetFunction.CountIfs(rng, ws1.Cells(i, 2).Value, rng2, ws1.Cells(i, 3).Value, rng3, "NW", rng4, "Basic Choice")
Next i
End With
End Sub
I would really appreciate some help to find a correct approach to solve my issue.
I am attempting to loop through all worksheets (except for "Sheet 1" and "Output".
All the above referenced worksheets contain data from cell A2 to last column and last row. I need to copy all the looped ranges (one below the other) in cell C2 in my "Output" worksheet.
Also I have a unique number in A1 in all worksheets (except for "Sheet 1" and "Output" that needs to be copied into B2 in my "Output" worksheet. The trick is (which i am struggling with) the value in A1 needs to be copied down B2 in my "Output" worksheet by the number A2:last row in all my looped worksheets.
Below is my code thus far:
Sub EveryDayImShufflingData()
Dim ws As Worksheet
Dim PasteSheet As Worksheet
Dim Rng As Range
Dim lRow As Long
Dim lCol As Long
Dim maxRow As Integer
Dim x As String
Set PasteSheet = Worksheets("Output")
Application.ScreenUpdating = False
'Loop through worksheets except "Sheet 1" and "Output"
For Each ws In ActiveWorkbook.Worksheets
If (ws.Name <> "Sheet1") And (ws.Name <> "Output") And (ws.Visible = True) Then
'Select the Worksheet
ws.Select
'With each worksheet
With ws
'Declare variables lRow and lCol
lRow = .Cells(Rows.Count, 1).End(xlUp).Row
lCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
'Set range exc. VIN
Set Rng = .Range(.Cells(2, 1), .Cells(lRow, lCol))
'Paste the range into "Output" worksheet
Rng.Copy
PasteSheet.Cells(Rows.Count, 3).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
x = .Cells(1, 1).Value
For i = 1 To lRow
PasteSheet.Cells(i, 2).End(xlUp).Offset(1, 0) = x
maxRow = maxRow + 1
Next
Application.CutCopyMode = False
Application.ScreenUpdating = True
End With
End If
Next ws
End Sub
Any assistance would be kindly appreciated
Try this:
Sub EveryDayImShufflingData()
Dim ws As Worksheet, copyRng As Range, lRow As Long, lCol As Long, PasteSheet As Worksheet
Set PasteSheet = Worksheets("Output")
For Each ws In ActiveWorkbook.Worksheets
If (ws.Name <> "Sheet1") And (ws.Name <> "Output") And (ws.Visible = True) Then
lRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
lCol = ws.Cells(2, ws.Columns.Count).End(xlToLeft).Column
Set copyRng = ws.Range(ws.Cells(2, 1), ws.Cells(lRow, lCol))
copyTargetCell = PasteSheet.Cells(Rows.Count, 3).End(xlUp).Row + 1
copyRng.Copy Destination:=PasteSheet.Range("C" & copyTargetCell)
Worksheets("Output").Range("B" & copyTargetCell & ":B" & (copyTargetCell + copyRng.Rows.Count - 1)) = ws.Range("A1")
End If
Next ws
End Sub
I have created macro that works like a vlookup but has split values. I would like to find value from second sheet of split values (separated by semicolon ) and copy and paste the description to new sheet.
The first loop goes through the list in sheet 2 and sets the value in a variable, the second loop through split values checks when there is exact match and the description is copied and pasted to the second sheet.
However - it doesn't work and I don't know what the problem is.
I have notification "type mismatch".
I tried vlookup with part text string but it doesn't work either.
Sub Metadane()
Dim ws As Worksheet
Dim aCell As Range, rng As Range
Dim Lrow As Long, i As Long
Dim myAr
Dim ws2 As Worksheet
Dim bCell As Range, rng2 As Range
Dim variable As String
'~~> Change this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("A1:A" & Lrow)
Set ws2 = ThisWorkbook.Sheets("Sheet2")
With ws2
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Set your range
Set rng2 = .Range("A1:A" & Lrow)
'~~> Loop trhough your range
For Each bCell In rng2
If Len(Trim(bCell.Value)) <> 0 Then
variable = bCell.Value
For Each aCell In rng
'~~> Skip the row if value in cell A is blank
If Len(Trim(aCell.Value)) <> 0 Then
'~~> Check if the cell has ";"
'~~> If it has ";" then loop through values
If InStr(1, aCell.Value, ";") Then
myAr = Split(aCell.Value, ";")
For i = LBound(myAr) To UBound(myAr)
If myAr = variable Then
Worksheets("sheet2").bCell(, 2).PasteSpecial xlPasteValues
Next i
Else
Worksheets("sheet2").bCell(, 2).PasteSpecial xlPasteValues
End If
End If
Next
End If
Next
End With
End Sub
I changed my code but it is still not work properly, I have a result:
try this
Sub test()
Dim Cl As Range, Key As Variant
Dim Dic As Object: Set Dic = CreateObject("Scripting.Dictionary")
Dic.CompareMode = vbTextCompare
With Sheets("Sheet1")
For Each Cl In .Range("A1:A" & .Cells.SpecialCells(xlCellTypeLastCell).Row)
If Cl.Value <> "" Then
Dic.Add Cl.Row & "|" & Replace(LCase(Cl.Value), ";", "||") & "|", Cl.Offset(, 1).Text
End If
Next Cl
End With
With Sheets("Sheet2")
For Each Cl In .Range("A1:A" & .Cells.SpecialCells(xlCellTypeLastCell).Row)
For Each Key In Dic
If Key Like "*|" & LCase(Cl.Value) & "|*" And Cl.Value <> "" Then
Cl.Offset(, 1).Value = Dic(Key)
Exit For
End If
Next Key
Next Cl
End With
End Sub
Output Result
Sub YourVLookup()
Dim rng As Variant, rng2 As Variant
Dim lastRow As Long, i As Long, j As Long, k As Long
Dim aCell As Variant, bCell As Variant
Dim myAr() As String, variable As String
lastRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:B"&lastRow)
lastRow = ThisWorkbook.Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
Set rng2 = ThisWorkbook.Worksheets("Sheet2").Range("A1:B"&lastRow)
For i = LBound(rng2, 1) To UBound(rng2, 1)
If Len(Trim(rng2(i, 1))) <> 0 Then
variable = rng2(i, 1)
For j = LBound(rng, 1) To UBound(rng, 1)
If Len(Trim(rng(j, 1))) <> 0 Then
If InStr(1, rng(j, 1), ";") > 0 Then
myAr = Split(rng(j, 1))
For k = LBound(myAr) To UBound(myAr)
If myAr(k) = variable Then
rng2(i, 2) = myAr(k)
End If
Next k
ElseIf rng(j, 1) = rng2(i, 1) Then
rng2(i, 2) = rng(j, 2)
End If
End if
Next j
End If
Next i
lastRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Worksheets("Sheet1").Range("A1:B"&lastRow) = rng
lastRow = ThisWorkbook.Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Worksheets("Sheet2").Range("A1:B"&lastRow) = rng2
End Sub
You were pasting something that you don't have copied already, you forgot to close a With, and you can't use bCell(,2), so
Try this :
Sub Metadane()
Dim ws As Worksheet
Dim aCell As Range, rng As Range
Dim Lrow As Long, i As Long
Dim myAr() As String
Dim ws2 As Worksheet
Dim bCell As Range, rng2 As Range
Dim variable As String
'~~> Change this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("A1:A" & Lrow)
End With
Set ws2 = ThisWorkbook.Sheets("Sheet2")
With ws2
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Set your range
Set rng2 = .Range("A1:A" & Lrow)
'~~> Loop trhough your range
For Each bCell In rng2
If Len(Trim(bCell.Value)) <> 0 Then
variable = bCell.Value
For Each aCell In rng
'~~> Skip the row if value in cell A is blank
If Len(Trim(aCell.Value)) <> 0 Then
'~~> Check if the cell has ";"
'~~> If it has ";" then loop through values
If InStr(1, aCell.Value, ";") Then
myAr = Split(aCell.Value, ";")
For i = LBound(myAr) To UBound(myAr)
If myAr(i) <> variable Then
Else
'You were pasting nothing with that
'.bCell(, 2).PasteSpecial xlPasteValues
.Cells(bCell.Row, 2) = aCell.Offset(0, 1).Value
End If
Next i
Else
'Same here
'.bCell(, 2).PasteSpecial xlPasteValues
.Cells(bCell.Row, 2) = aCell.Offset(0, 1).Value
End If
End If
Next aCell
End If
Next bCell
End With
End Sub