My problem is pretty straight-forward: how do I define the range from a certain cell to the end of the row?
If you would know what am I trying to achieve, you would understand the situation better: I want to sort rows individually but every row's datas start at 17. column, so I'm trying to make the sorting from 17. column to end of the column count.
Thanks in advance!
Defining range in VBA: Dim rng As Range.
Setting range (since it's object, you must use Set keyword): Set rng = Range("A1:B2")
or
Set rng = Range(Cells(1, 1), Cells(2, 2)) - both are equivalent.
So, if you want to specify custom range in ONE row starting from 17th column, you must also know where the rows ends, you can do that in two ways:
Dim lastCol As Long
lastCol = Cells(rowNumber, 17).End(xlToRight).Column
'alternative, but not equivalent
lastCol = Cells(rowNumber, Columns.Count).End(xlToLeft).Column
Where rowNumber is partciular number of of a row.
Now, having lastCol we can define the range:
Set rng = Range(Cells(rowNumber, 17), Cells(rowNumber, lastCol))
Again, rowNumber is partciular number of of a row.
Related
VBA question using Excel 2016 (64 bit)
I have header data in the first two columns (A:B) and the top row (1). I would like to dynamically paste a formula downward, starting from cell C2, to the last row and the last column. The working prototype is as follows:
Dim LstCol As Long
LstCol = Cells(1, Columns.Count).End(xlToLeft).Column
Range(Cells(2, "C"), Cells(2, LstCol)).Value = "=INDEX(RC1,MATCH(R1C,RC2,0))"
Dim LstRow As Long
LstRow = Cells(1, Rows.Count).End(xlUp).Row
Range(Cells(2, "C"), Cells(2, LstRow)).Value = "=INDEX(RC1,MATCH(RC1,R2C,0))"
The first Dim works as intended. The formula is successfully deployed throughout the second row to the final column (or perhaps it starts at the last column and moves leftward). However, the second Dim stops on an error. I'm unsure how to spread the data from the last row (to the last column) upwards to the second row (and the corresponding last column).
In my example, the first two columns have header data from 1 to 5330 (A1:B5330). I also have header data in the first row (C1:AX1). My target is to fill the formula =INDEX($A2,MATCH(D$1,$B2,0)) from C2:AX5330 dynamically.
Where am I going wrong?
You need to properly qualify your instances of Range and Cells with a worksheet. You can either directly do this, dim a worksheet variable, or use a With block like so:
Dim LRow as Long
With ThisworkBook.Sheets("????")
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("C2:AX5330").Formula = "=INDEX($A2,MATCH(D$1,$B2,0))" 'Make sure your cell references are correct here
.Range("C2:AX5330").Value = .Range("C2:AX55330").Value 'Place as values instead of formula
End With
I'm trying to get this cell to total a range from another worksheet but I keep getting stuck. The range rows and columns vary but the starting point is always C2. I need to total from C2 to the rest of the used range (aka exclude columns A and B as well as row 1 but include everything else).
Please help if you can.
Range("A1").Formula = "Wage Totals"
Range("A2").Formula = "=SUM(" & ActiveWorkbook.Sheets("Wage").Range(Cells(2, 3), Cells.SpecialCells(xlCellTypeLastCell)).Address(False, False) & ")"
Check out this link Using SUM() in VBA
You can use that idea to change your code to:
Dim lastCol As Long
Dim lastRow As Long
lastCol = Sheets("Wage").Cells(1, Sheets("Wage").Columns.Count).End(xlToLeft).Column
lastRow = Sheets("Wage").Cells(Sheets("Wage").Rows.Count, 1).End(xlUp).Row
Range("A1").Value = "Wage Totals"
Range("A2").Value = WorksheetFunction.Sum(Sheets("Wage").Range(Sheets("Wage").Cells(2, 3), Sheets("Wage").Cells(lastRow, lastCol)))
This is pretty naive solution tho becuase it assumes the usedrange limits can be found by looking for last used row on Col "A" and last used col on Row 1. You can change that method of finding the limits.
I have a project that I am working on where multiple conditions are checked across all rows and many columns. The issue is that columns are added/removed from the sheet, and, at present, that results in all of my cell(row,column) references being off + outputting incorrect information. I'm wondering if there's a way to make my column references more robust so that they automatically find the correct headers and use them when checking? Would a solution to this problem be able to account for multiple columns containing the exact same header text?
Basically:
No blank columns
Column headers have repeats (e.g., Column 1 header: "Financials"; Column 15 header: "Financials")
Columns are shifting right and left based on adding/removing columns from sheet
Please find a short sample of my current code below with notes:
Dim i As Integer
Dim lastRow As Long
Dim lastCol As Long
lastRow = Range("A1").End(xlDown).Row
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 2 To lastRow
Select Case Cells(i, 14).Value
Case Is = "Yes"
Select Case True
Case Cells(i, 63).Value = 6 And _
(IsEmpty(Cells(i, 77)) Or IsEmpty(Cells(i, 93)) Or IsEmpty(Cells(i, 109)) Or _
IsEmpty(Cells(i, 125)) Or IsEmpty(Cells(i, 141)) Or IsEmpty(Cells(i, 157)))
Cells(i, 174).Value = "True" '^THESE CELL VALUES ALL HAVE THE SAME COLUMN HEADER TITLE
If the table is consistent - starting at A1 and occupying a contiguous block - then Range("A1").CurrentRegion will reference the table.
You can then use .CreateNames to name the columns (that is, using Named Ranges) according to their headings.
Dim rngTable As Range
Dim rng As Range
Set rngTable = Range("A1").CurrentRegion
rngTable.CreateNames True, False, False, False
' that is, based on the first row headings
Range("Salary").Select 'prove it works
'if necessary, iterate the cells of the column,
For Each rng In Range("Salary")
rng.Value = rng.Value + 10
Next 'rng
If a column heading is duplicated ("Financial"), though, then you'll be asked to confirm and the second occurrence will overrule the first. (Or you could say "No" and the first occurrence will be named.) In which case, it is preferable that you first correct these duplicate headings.
Correcting the duplicate headings is not necessarily straight forward, but something that you should resolve anyway. If it is a specific word "Financials" (or words) that could be duplicated then this makes the task easier. You could count how many occurrences there are, and correct the second, etc., to "Financials2".
One easy way to to assign a Name to the column. Say column N has the header "Payments". First assign the Name "Payments" to that column:
Then in VBA we can code like:
Sub dural()
Dim rng As Range, colly As Long
Set rng = Range("Payments")
colly = rng.Column
For i = 2 To 100
If Cells(i, colly) = "whatever" Then
MsgBox "Help"
End If
Next i
End Sub
The code will continue to work even if you add/remove columns beforre column N.
I am looking for code for two different types of selection. One code would select in an L shape all of the rows in one column and all of the columns in one row. In the example of having data in the range A1:A10, and data in row 10 only from col A - K. The selection would look like an L. How can you do this without knowing how many rows or columns have data in them?
The second code would have the same data, but need to select the whole range A1:K10 in that example, but the code would need to select whatever range had the data.
i found the answer. i have to do a union. here is the code with the union at the end.
Sub mywork()
Dim ws As Worksheet
Dim lRow As Long, lCol As Long
Dim rng As Range
'~~> Set this to the relevant worksheet
Set ws = [Sheet1]
With ws
'~~> Get the last row and last column
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
lCol = .Cells(lRow, .Columns.Count).End(xlToLeft).Column
'~~> Set the range
Set rng = .Range(.Cells(lRow, 1), .Cells(lRow, lCol))
End With
Set rng = Application.Union(Range("A1:A" & lRow), rng)
rng.Select
End Sub
activesheet.usedrange.address should tell you the used range.
In your case something like this should work: [sheet1].usedrange.select (Replaces all the code in the module)
The benefit here is the fact that you are not hard coding "A1:A" against the last identified cell, works well if you have blank rows at the top.
I need to delete a range of rows using two named ranges
Current find the column numbers for the last column (lastColumn) and then the column 6 spots behind it (colrange)
Dim lastColumn As Integer
With ActiveSheet
lastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
colrange = lastColumn - 6
I want to delete the columns in the range colrange:lastColumn but not sure how to do this?
Range(Cells(1,colRange),Cells(1,lastColumn)).EntireColumn.Delete
you can simply use:
Range(Columns(colRange),Columns(lastColumn)).Delete
or directly:
With ActiveSheet
.Range(.Columns(.Cells(1, .Columns.Count).End(xlToLeft).Column - 6), .Columns(.Cells(1, .Columns.Count).End(xlToLeft).Column)).Delete
End With