I have a Table that I created through a previous Macro.
With the help from another question, I was able to find “All Other” in Column B, and insert a formula in the adjacent column.
PrintScreen:
Now I would like to copy the formula from the Unknown Active Cell, and paste it into the adjacent Columns: D, E, G, H, I, J, and L Offset – 0 Rows.
I currently have:
Sub AllOther()
Dim ws As Worksheet
Dim aOther As Range
Dim DataLastRow As Long
Set ws = ActiveSheet
DataLastRow = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole)
If Not aOther is Nothing Then
aOther.Offset(0, 1).Formula = "=SUM(" & aOther.Offset(3, 1).Address & ":" & ws.Cells(DataLastRow,3).Address & ")"
Else
MsgBox """All Other"" not found in column."
End If
'Copy/Paste into other Columns
End Sub
Q1/ What is the "Unknown Active Cell" you are referring to?
Q2/ What do you you want to sum in the formula
=SUM(" & aOther.Offset(3, 1).Address & ":" & ws.Cells(DataLastRow,3).Address & ")" ?
The beginning of the range aOther.Offset(3, 1).Address is 3 rows below aOther and the end of the range is anywhere.
Anyway it will be easier if in the formula you do not mix an offset of aOther with an offset of ws.
3/ doing so would enable you to loop as in the following code
Sub AllOther()
Dim ws As Worksheet
Dim aOther As Long
Dim aOtherRow As Integer ' row
Dim arr As Variant
arr = Array(3, 4, 5, 7, 8, 9, 11) ' columns to sum
Set ws = ActiveSheet
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole).Row
If Not aOther Is Nothing Then
aOtherRow = aOther.Row
For Each i In arr
ws.Cells(aOtherRow, i).Formula = "=SUM(" & ws.Cells(FirstRow, i).Address & ":" & ws.Cells(LastRow, i) & ")"
Next i
Else
MsgBox """All Other"" not found in column."
End If
End Sub
In which FirstRow and LastRow depend of the answer to Q2
------------------- Edit after Cari Day answers ------------------------
Sub AllOther()
Dim ws As Worksheet
Dim aOther As Range
Dim aOtherRow As Long
Dim DataFirstRow As Long
Dim DataLastRow As Long
Dim col as integer
Dim ColumnsArray As Variant
ColumnsArray = Array(3, 4, 5, 7, 8, 9, 11) ' columns to sum
Set ws = ActiveSheet
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole)
If Not aOther Is Nothing Then
aOtherRow = aOther.Row
DataFirstRow = aOtherRow + 1
DataLastRow = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
For Each col In ColumnsArray
ws.Cells(aOtherRow, col).Formula = "=SUM(" & ws.Cells(DataFirstRow, col).Address & ":" & ws.Cells(DataLastRow, col).Address & ")"
Next col
Else
MsgBox """All Other"" not found in column."
End If
End sub
Related
Hope you're doing great, need help with below code that is supposed to match first column from 2 files then vlookup and copy paste the matched results. the problem is that i'm limited by vlookup range that only works for one column so i tried to make a loop to make it work on multiple number of cells as shown below but it's not working, any help or hints would be really welcomed, Thanks.
edit
the problem lies where iis used in the funcStr for the vlooukp table range and column's number, i need the range to be increased and column number to constinatly change to get the whole row copied instead.
Sub solution()
Dim oldRow As Integer
Dim newRow As Integer
Dim lrow_output As Integer
Dim WB_Input As Workbook
Dim WB_Output As Workbook
Dim WS_Input As Worksheet
Dim WS_Output As Worksheet
Dim funcStr As String
Dim i As Integer
Set WB_Input = Workbooks("File.xlsm")
Set WB_Output = Workbooks("output1.xlsx")
Set WS_Input = WB_Input.Worksheets("input")
Set WS_Output = WB_Output.Worksheets("Sheet1")
With WS_Output
lrow_output = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
For i = 2 To 6
With WS_Input
funcStr = "=IFERROR(VLOOKUP(" & Cells(1, 1).Address(False, False) & "," & "'[" & WB_Input.Name & "]" & .Name & "'!" & Range(.Columns(1), .Columns(i)).Address & ",i,0),"""")"
End With
With WS_Output
.Cells(1, i).Formula = funcStr
.Cells(1, i).Copy
Range(.Cells(1, i), .Cells(lrow_output, i)).PasteSpecial xlPasteFormulas
WS_Output.Calculate
Range(.Cells(1, i), .Cells(lrow_output, i)).Copy
Range(.Cells(1, i), .Cells(lrow_output, i)).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
Next i
End Sub
I would like to compare cells in Worksheet 2 against Worksheet 1.
First check for matching cells in range A for both Worksheets 1 and 2.
Next, if there are no matches, check for matching cells in range B for both Worksheets 1 and 2, otherwise if there are matches, check the next cell in range A.
If there are no matches as well, copy these non-matching cells in ranges A and B in Worksheet 2 to a new worksheet, Worksheet 3.
Here are my worksheets' layout:
Worksheet 1 -
Worksheet 2 -
Worksheet 3 -
Here is my code (which is not working as intended):
Dim Cl As Range, Rng As Range, Dic As Object
Set Dic = CreateObject("scripting.dictionary")
With Dic
For Each Cl In MyWorkSheet1Name.Range("A2:B" & MyWorkSheet1Name.Range("B" & Rows.Count).End(xlUp))
.Item(Cl.Value) = Empty
Next Cl
For Each Cl In MyWorkSheet2Name.Range("A2:B" & MyWorkSheet2Name.Range("B" & Rows.Count).End(xlUp))
If Not .Exists(Cl.Value) Then
If Rng Is Nothing Then Set Rng = Cl Else Set Rng = Union(Rng, Cl)
End If
Next Cl
End With
If Not Rng Is Nothing Then
Rng.EntireRow.Copy MyWorkSheet3Name.Range("A" & Rows.Count).End(xlUp)
End If
How do I get the code to run as intended?
Many thanks!
You could try this:
Dim lRow1 As Long, lRow2 As Long
lRow1 = Sheets(1).Range("A" & Sheets(1).Rows.Count).End(xlUp).Row
lRow2 = Sheets(2).Range("A" & Sheets(2).Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
With Sheets(3)
Sheets(1).Range("A1:B" & lRow1).Copy Destination:=.Range("A1")
Sheets(2).Range("A2:B" & lRow2).Copy Destination:=.Range("A" & lRow1 + 1)
.Range("C2").Formula = "=COUNTIFS($A$2:$A$" & lRow1 + lRow2 - 1 & ",A2,$B$2:$B$" & lRow1 + lRow2 - 1 & ",B2)"
.Range("C2").AutoFill Destination:=.Range("C2:C" & lRow1 + lRow2 - 1)
.Range("A1").AutoFilter Field:=3, Criteria1:=">1"
.Rows("2:" & lRow1 + lRow2 - 1).SpecialCells(xlCellTypeVisible).Delete
.Range("A1").AutoFilter
.Columns(3).EntireColumn.Delete
End With
Application.ScreenUpdating = True
I am trying to write a macro that copies a row if a cell in that row contains text (For ex: Mumbai, Delhi etc) from Column C.
For example if there are 30 rows but only 15 contains text(Mumbai & Delhi) in column C. I want to copy those 15 rows and paste them into "Sheet2" I was using the below code. however it is copying all the filled rows. however my requirement is the code should only need to copy columns of a, b, c, d, f, g, h, i, l & m to Sheet2.
Sub testPasteinSh2()
Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
Dim strSearch1 As String, strSearch2 As String
strSearch1 = "Mumbai" 'or combo value...
strSearch2 = "Delhi" 'or something else...
Set sh1 = ActiveSheet 'use here your worksheet
Set sh2 = Worksheets("Sheet2") 'use here your sheet
lastR1 = sh1.Range("C" & Rows.count).End(xlUp).Row
lastR2 = sh2.Range("A" & Rows.count).End(xlUp).Row + 1
Set rng = sh1.Range("C2:C" & lastR1)
For Each cel In rng.cells
If cel.Value = strSearch1 Or cel.Value = strSearch2 Then
If rngCopy Is Nothing Then
Set rngCopy = sh1.Rows(cel.Row)
Else
Set rngCopy = Union(rngCopy, sh1.Rows(cel.Row))
End If
End If
Next
If Not rngCopy Is Nothing Then
rngCopy.Copy Destination:=sh2.cells(lastR2, 1)
End If
End Sub
Can you please help me. Thank you in Advance.
It looks difficult to ask a clear question...
It happens I know what you need from a previous question. Supposing that you did not change your mind, please test the next code:
Sub testPasteinSh2Bis()
Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
Dim strSearch1 As String, strSearch2 As String
'a, b, c, d, f, g, h, i, l 'columns to be copied
strSearch1 = "Mumbai" 'or combo value...
strSearch2 = "Delhi" 'or something else...
Set sh1 = ActiveSheet 'use here your worksheet
Set sh2 = sh1.Next 'use here your sheet
lastR1 = sh1.Range("C" & Rows.count).End(xlUp).Row
lastR2 = sh2.Range("A" & Rows.count).End(xlUp).Row + 1
Set rng = sh1.Range("C2:C" & lastR1)
For Each cel In rng.cells
If cel.Value = strSearch1 Or cel.Value = strSearch2 Then
If rngCopy Is Nothing Then
Set rngCopy = sh1.Range(sh1.Range("A" & cel.Row & ":D" & cel.Row).Address & "," & _
sh1.Range("F" & cel.Row & ":I" & cel.Row).Address & "," & sh1.Range("L" & cel.Row).Address)
Else
Set rngCopy = Union(rngCopy, sh1.Range(sh1.Range("A" & cel.Row & ":D" & cel.Row).Address & "," & _
sh1.Range("F" & cel.Row & ":I" & cel.Row).Address & "," & sh1.Range("L" & cel.Row).Address))
End If
End If
Next
If Not rngCopy Is Nothing Then
rngCopy.Copy Destination:=sh2.cells(lastR2, 1)
End If
End Sub
It should copy the columns a, b, c, d, f, g, h, i, l for the matching cases...
You could try this:
Sub Macro1()
Dim lastrow As Long, erow As Long
Dim rng1 As Range
Dim rng2 As Range
'choose an empty column, in my example is O.
With Worksheets("Sheet1")
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Range("O2:O" & lastrow).FormulaR1C1 = "=IF(OR(RC[-12]=""Mumbai"",RC[-12]=""Delhi""),1,"""")" 'here is -12 because difference between column C and O is 3. Change it according your needs
Set rng1 = .Range("O2:O" & lastrow).SpecialCells(xlCellTypeFormulas, 1)
For Each rng2 In rng1.Cells
erow = Worksheets("Sheet2").Cells(Worksheets("Sheet2").Rows.Count, 1).End(xlUp).Row
Worksheets("Sheet2").Range("A" & erow + 1 & ":M" & erow + 1) = .Range("A" & rng2.Row & ":M" & rng2.Row).Value 'this will copy the full row of data from A to M
Next rng2
Set rng1 = Nothing
.Range("O2:O" & lastrow).Clear
End With
'delete the columns copied but you don't want like E, J,K
With Worksheets("Sheet2")
.Columns("E:E").Delete
.Columns("J:K").Delete
End With
End Sub
This code will copy the row of data and delete the columns you don't want.
In case that's not posible, then you can copy single ranges. You could replace line
Worksheets("Sheet2").Range("A" & erow + 1 & ":M" & erow + 1) = .Range("A" & rng2.Row & ":M" & rng2.Row).Value 'this will copy the full row of data from A to M
with
Worksheets("Sheet2").Range("A" & erow + 1).Value = .Range("A" & rng2.Row).Value 'a single cell
Probably you can adapt this to your needs.
I have another VBA question please.
I have a Table in Excel, I want to find the text: "All Other" that will always be in Column B, but may not be in the same Row #.
After I find "All Other" cell, I want to enter a Sum formula in the next column over (0,1).
The formula would Sum the unknown range starting with 3 rows down from the Activecell to the end of the data.
I'm getting an error: Invalid or unqualified reference.
PrintScreen:
I currently have:
Dim ws As Worksheet
Dim aOther As Range
Dim DataLastRow As Range
Set ws = ActiveSheet
Set DataLastRow = ws.Cells.Range(ws.Rows.Count, 1).End(xlUp).Rows
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole)
ActiveCell.Offset(0, 1).Formula = "=SUM(" & .Offset(3, 0) & DataLastRow & ")"
Dim ws As Worksheet
Dim aOther As Range
Dim DataLastRow As Long
Set ws = ActiveSheet
DataLastRow = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole)
If Not aOther is Nothing Then
aOther.Offset(0, 1).Formula = "=SUM(" & aOther.Offset(3, 1).Address & ":" & ws.Cells(DataLastRow,3).Address & ")"
Else
MsgBox """All Other"" not found in column."
End If
I adapted code I found online.
It finds the string "car" in column A and returns the rows as an array
It assigns a variable to the length of the array (how many matches it found)
It assigns a variable to generate a random number between 0 and the length of the array
It then prints a random matching row's value into K3
Dim myArray() As Variant
Dim x As Long, y As Long
Dim msg As String
With ActiveSheet.Range("A1:A" & ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row)
Set c = .find("Car", LookIn:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Address
Do
ReDim Preserve myArray(y)
myArray(y) = c.Row
y = y + 1
Set c = .findNext(c)
If c Is Nothing Then
GoTo DoneFinding
End If
Loop While c.Address <> firstAddress
End If
DoneFinding:
End With
For x = LBound(myArray) To UBound(myArray)
msg = msg & myArray(x) & " "
Next x
ArrayLen = UBound(myArray) - LBound(myArray)
random_index = WorksheetFunction.RandBetween(0, ArrayLen)
MsgBox myArray(random_index)
Dim test As String
test = "B" & myArray(random_index)
Range("K3").Value = Range(test)
Example
I'm struggling with adapting the find code to allow for multiple criteria. So in my example, it finds "Car". What if I want to find matches that had "Car" in column A and "Red" in column D?
I tried
With ActiveSheet.Range("A1:A" & "D1:D" & ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row & ActiveSheet.Range("D" & Rows.Count).End(xlUp).Row)
Set c = .find("Car", "Red", LookIn:=xlValues)
I get type mismatch on the Set line.
In case it is confusing, it currently looks for a string e.g. "Car" but I will eventually link this to the variable which will be assigned to a data validation list. So if the user chooses "car" from a drop down list, this is what it will search for.
Maybe Advancde Filter is something that fit your needs:
Example Code
Option Explicit
Public Sub FilterData()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("YourSheetName")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim CriteriaRange As Range
Set CriteriaRange = ws.Range("A1", "E2")
Dim DataRange As Range
Set DataRange = ws.Range("A4", "E" & LastRow)
DataRange.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=CriteriaRange, Unique:=False
End Sub
Public Sub ShowAll()
On Error Resume Next
ActiveSheet.ShowAllData
On Error GoTo 0
End Sub
Edit according comment:
You can use the advanced filter and then loop through the filter results:
Option Explicit
Public CurrentRow As Long
Public Sub FilterData()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("YourSheetName")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim CriteriaRange As Range
Set CriteriaRange = ws.Range("A1", "E2")
Dim DataRange As Range
Set DataRange = ws.Range("A4", "E" & LastRow)
DataRange.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=CriteriaRange, Unique:=False
End Sub
Public Sub ShowAll()
On Error Resume Next
ActiveSheet.ShowAllData
CurrentRow = 1
On Error GoTo 0
End Sub
Public Sub GetNextResult()
FilterData
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("YourSheetName")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim DataRange As Range
Set DataRange = ws.Range("A4", "E" & LastRow)
Dim FilteredData As Range
Set FilteredData = DataRange.Resize(ColumnSize:=1).SpecialCells(xlCellTypeVisible)
If CurrentRow + 1 > FilteredData.Cells.Count Then
CurrentRow = 1
End If
CurrentRow = CurrentRow + 1
Dim i As Long
Dim Cell As Variant
For Each Cell In FilteredData
i = i + 1
If i = CurrentRow Then
Cell.EntireRow.Select
'or
'MsgBox Cell.Value & vbCrLf & Cell.Offset(0, 1) & vbCrLf & Cell.Offset(0, 2) & vbCrLf & Cell.Offset(0, 3) & vbCrLf & Cell.Offset(0, 4)
End If
Next Cell
End Sub