So I have a constant 7 number of ranges which are all one cell wide and a large, arbitrary height which is the same between them. Is it possible to join the ranges so that I have one range that only consists of all 7 ranges? I have tried the UnionRange function but it returns numbers far larger than to be expected.
This is what I have so far:
' acquire the range of each column, using its coumn number and the user-defined Col_Letter function
Dim rng1 As Range
Set rng1 = Sheets("sheet_name").Range(Col_Letter(col_1) & ":" & Col_Letter(col_1) & LRow)
Dim rng2 As Range
Set rng2 = Sheets("sheet_name").Range(Col_Letter(col_2) & ":" & Col_Letter(col_2) & LRow)
Dim rng3 As Range
Set rng3 = Sheets("sheet_name").Range(Col_Letter(col_3) & ":" & Col_Letter(col_3) & LRow)
Dim rng4 As Range
Set rng4 = Sheets("sheet_name").Range(Col_Letter(col_4) & ":" & Col_Letter(col_4) & LRow)
Dim rng5 As Range
Set rng5 = Sheets("sheet_name").Range(Col_Letter(col_5) & ":" & Col_Letter(col_5) & LRow)
Dim rng6 As Range
Set rng6 = Sheets("sheet_name").Range(Col_Letter(col_6) & ":" & Col_Letter(col_6) & LRow)
Dim rng7 As Range
Set rng7 = Sheets("sheet_name").Range(Col_Letter(col_7) & ":" & Col_Letter(col_7) & LRow)
' Join the ranges of each column into one range
Dim UnionRange As Range
Set UnionRange = Union(rng1, rng2, rng3, rng4, rng5, rng6, rng7)
Debug.Print "Width of UnionRange: " & UnionRange.width
Debug.Print "Height of UnionRange: " & UnionRange.height
You can't run UNION() on ranges from different worksheets. A Range is limited to a set of cells on a single sheet.
EDIT#1:
I suspect your Debug.Print. Your are printing a pixel-related variable rather than a row count
Sub dural()
Dim r As Range
Set r = Range("A1:C5")
MsgBox r.Height & vbCrLf & r.Rows.Count
End Sub
Try using unionrange.rows.count and unionrange.columns.count instead its is possible that width and height uses difference between border cell addresses instead of counting it
I solved it by acquiring the row number bounds like so:
Dim FirstRow As Long, LastRow As Long
With Get_Workbook.Sheets("Sheet_Name").UsedRange
FirstRow = .Row
LastRow = .Rows(UBound(.Value)).Row
End With
From there, I modified my code to this format:
Dim rng1 As Range
Set rng1 = Get_Workbook.Sheets("Sheet_Name").Range(Col_Letter(col_1) & FirstRow & ":" & Col_Letter(col_1) & LastRow)
This way, I have already found the correct column letter with my Col_Letter function and I can get the correct, used range as well.
Note that Get_Workbook and Col_Letter are user-defined functions.
Related
So the situation is that I would like to copy 4 columns with variable lengths into one column containing all the data from these 4. The problem is I loose data in the process.
As an example it should be 693 rows but I only get 648 rows all in all.
I'm relatively new to VBA and have come up with these lines of code.
Sub Copy()
Dim RngA As Range, RngB As Range, RngC As Range, RngD As Range, Rng As Range
Set RngA = Range(Range("I2"), Range("I" & Rows.Count).End(xlUp))
Set RngB = Range(Range("J2"), Range("J" & Rows.Count).End(xlUp))
Set RngC = Range(Range("K2"), Range("K" & Rows.Count).End(xlUp))
Set RngD = Range(Range("L2"), Range("L" & Rows.Count).End(xlUp))
Range("O2").Resize(RngA.Count).Value = RngA.Value
Range("O" & RngA.Count + 1).Resize(RngB.Count).Value = RngB.Value
Range("O" & RngB.Count + 1).Resize(RngC.Count).Value = RngC.Value
Range("O" & RngC.Count + 1).Resize(RngD.Count).Value = RngD.Value
With Sheets("Keywords")
Columns("O:O").Sort Key1:=.Range("=O1"), Order1:=xlAscending, Header:=xlYes
End With
End Sub
See my comment above, but here is an alternative approach using arrays which saves having to set up multiple similarly-named range variables.(Btw am assuming everything is on the Keywords sheet.)
Sub Copy()
Dim vRng(1 To 4) As Range, i As Long
With Sheets("Keywords")
For i = LBound(vRng) To UBound(vRng)
Set vRng(i) = .Range(.Cells(2, i + 8), .Cells(.Rows.Count, i + 8).End(xlUp))
Next i
For i = LBound(vRng) To UBound(vRng)
.Range("O" & Rows.Count).End(xlUp)(2).Resize(vRng(i).Count).Value = vRng(i).Value
Next i
.Columns("O:O").Sort Key1:=.Range("O1"), Order1:=xlAscending, Header:=xlYes
End With
End Sub
I have been trying to loop through a range of cells and apply an index match . So, far, the index match is working only for the first row of the range (so its not looping). I am providing the code.
Dim LastRow As Long
Sheets("REPORT").Select
LastRow = Range("A" & Rows.Count).End(xlUp).Row
Range("C2:C" & LastRow).Formula "=INDEX('2609'!C:C,MATCH('REPORT'!A2,'2609'!E:E,FALSE))"
Write
Range("C2:C" & LastRow).Formula "=INDEX('2609'!C:C,MATCH('REPORT'!A2,'2609'!E:E,FALSE))"
as
Range("C2:C" & LastRow).Formula ="=INDEX('2609'!C:C,MATCH('REPORT'!A2,'2609'!E:E,FALSE))"
you are missing = sign.
Your code can be written as
Sub Demo()
Dim ws As Worksheet
Dim LastRow As Long
Set ws = ThisWorkbook.Sheets("REPORT")
With ws
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("C2:C" & LastRow).Formula = "=INDEX('2609'!C:C,MATCH('REPORT'!A2,'2609'!E:E,FALSE))"
End With
End Sub
I am trying to have vba create a formula for two ranges within the same data set, as input into variables lastRow and lastRow2. However, when I try to create and calculate the formula, instead of getting the value of the last cell I get a zero. Offending code below:
Dim lastRow As Long
Dim lastRow2 As Long
lastRow = Range("A" & Rows.Count).End(xlUp).Row
lastRow2 = Range("M" & Rows.Count).End(xlUp).Row
...
'Calculate ATRT 2014 at cell B4
Range("B6").Formula = "=(SUM(J11:J" & lastRow & ")/ SUM(I11:I" & lastRow & "))"
Range("E6").Formula = "=(SUM(U11:U" & lastRow2 & ")/ SUM(T11:T" & lastRow2 & "))"
Range("H6").Formula = "=E6-B6"
Running this gets two formulas: =(SUM(J11:J0)/ sum(I11:I0)) and =(SUM(U11:U0)/ SUM(T11:T0)). Why is the end of the range a zero???
I'm pretty sure what is happening if you are not defining which worksheet the range() and row() objects are on so VBA is guessing and probably guessing incorrectly. Try adding a worksheet object and then defining all the ranges and rows to use be on that worksheet.
Dim lastRow As Long
Dim lastRow2 As Long
Dim ws As Worksheet
Set ws = ActiveSheet
lastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
lastRow2 = ws.Range("M" & ws.Rows.Count).End(xlUp).Row
'...
'Calculate ATRT 2014 at cell B4
ws.Range("B6").Formula = "=(SUM(J11:J" & lastRow & ")/ SUM(I11:I" & lastRow & "))"
ws.Range("E6").Formula = "=(SUM(U11:U" & lastRow2 & ")/ SUM(T11:T" & lastRow2 & "))"
ws.Range("H6").Formula = "=E6-B6"
I have some code which I know works, I am applying a SUMIF formula to a range of cells. It works but it add a load of extra row at the bottom that shouldn't be there. I tried adding in a do until loop but it gets stuck in an infinite loop and crashes.
This is my first lot of code which works but adds the extra row in only on the columns which have been copied over.
Dim z As Workbook 'Budget Workbook
Dim y As Workbook 'Formatted - current workbook
Dim lastRow As Integer
Dim budgLastRow As Integer
Dim rng As Range
Set y = Workbooks("DLT.xlsm")
Set z = Workbooks.Open("C:\Reports\Budget.xlsx")
'Apply function to columns to pull costing data
With y.Worksheets("DLT")
lastRow = Cells(Rows.Count, 5).End(xlUp).Row
For Each rng In .Range("AI22:AI" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!H:H)"
rng.Value = rng.Value
Next rng
For Each rng In .Range("AJ22:AJ" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!I:I)"
rng.Value = rng.Value
Next rng
For Each rng In .Range("AN22:AN" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!E:E)"
rng.Value = rng.Value
Next rng
For Each rng In .Range("AO22:AO" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!G:G)"
rng.Value = rng.Value
Next rng
End With
I think the other additional rows have been copied because the budget workbook contains more data then the formatted work book. I have know thought to possibly delete the other unnecessary row which have been copied cross.
So I have added this small piece of code in
With y.Worksheets("Formatted")
lastRow = Cells(Rows.Count, 5).End(xlUp).Row - 1
budgLastRow = Cells(Rows.Count, 35).End(xlUp).Row
Rows("AI" & lastRow & ":AO" & budgLastRow).EntireRow.Delete
End With
I get an application-defined error Object defined error on the line
Rows("AI" & lastRow & ":AO" & budgLastRow).EntireRow.Delete
This is probably not the most efficient way to do this, but its the only way I could think of. I am fairly new to VBA only been coding a couple of months so mostly just try out different ways and see what works. Can anyone help me please.
You didn't properly qualify the ranges for the lastRow variable:
lastRow = .Cells(.Rows.Count, 5).End(xlUp).Row
Note the dots before Cells and Rows.
A couple of additional points:
Always use Long rather than Integer for row variables as there are more rows in a sheet than an Integer can hold.
You don't need to loop to put the same formula in a column of cells.
Dim z As Workbook 'Budget Workbook
Dim y As Workbook 'Formatted - current workbook
Dim lastRow As Long
Dim budgLastRow As Long
Set y = Workbooks("DLT.xlsm")
Set z = Workbooks.Open("C:\Reports\Budget.xlsx")
'Apply function to columns to pull costing data
With y.Worksheets("DLT")
lastRow = .Cells(.Rows.Count, 5).End(xlUp).Row
With .Range("AI22:AJ" & lastRow)
.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E22,'[Budget.xlsx]DynamicReport'!H:H)"
.Value2 = .Value2
End With
With .Range("AN22:AN" & lastRow)
.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E22,'[Budget.xlsx]DynamicReport'!E:E)"
.Value2 = .Value2
End With
With .Range("AO22:AO" & lastRow)
.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E22,'[Budget.xlsx]DynamicReport'!G:G)"
.Value2 = .Value2
End With
End With
I have been attempting to solve this for a couple of days and have been able not come up with or find a similar solution. I am trying to highlight duplicates in a single column where their are distinct values in another.
For example occasionally in column G there are duplicate names but they only need to be marked(highlighted) when the value column D is unique. So using the example below the end result should only highlight Elizabeth Moore.
Column D Column G
116023339 Alan Fluder
116023339 Alan Fluder
116023347 Elizabeth Moore
116025757 Elizabeth Moore
116025048 A. Lavoie
If it helps below is the code I used as my starting point.
Sub test()
Dim cel As Variant
Dim myCell As Variant
Dim myrng As Range
Dim myRange As Range
Dim CellValue As Long
Set myrng = Range("G2:G" & Range("G" & Rows.Count).End(xlUp).Row)
Set myRange = Range("D2:D" & Range("D" & Rows.Count).End(xlUp).Row)
For Each cel In myrng
If Application.WorksheetFunction.CountIf(myrng, cel) > 1 Then
For Each myCell In myRange
If Application.WorksheetFunction.CountIf(myRange, myCell) = 1 Then
myCell.Offset(0, 3).Interior.ColorIndex = 6
End If
Next myCell
End If
Next cel
End Sub
I should add that my current solution now is to separate the loops where one highlights all the column G dups then the second loop unhighlights where column D is duped.
If you can use formulas #Tim's suggestion works well. To fix the VBA:
Option Explicit
Sub test()
Const ROW_OFFSET As Byte = 2
Dim cel As Range
Dim rng1 As Range
Dim rng2 As Range
Dim cRow As Long
Dim lRow As Long
Set rng1 = Range("G" & ROW_OFFSET & ":G" & Range("G" & Rows.Count).End(xlUp).Row)
Set rng2 = Range("D" & ROW_OFFSET & ":D" & Range("D" & Rows.Count).End(xlUp).Row)
With Application.WorksheetFunction
For Each cel In rng1
If .CountIf(rng1, cel) > 1 Then
If .CountIf(rng2, rng2.Cells(cel.Row - (ROW_OFFSET - 1), 1)) = 1 Then
cel.Interior.ColorIndex = 6
End If
End If
Next cel
End With
End Sub
The inner For is not needed if columns are synchronized
I used the ROW_OFFSET constant to emphasize the alignment between columns
.