VBA Excel - Using a variable to determine cell location - vba

I don't exactly know how to formulate my question since so I'll just give an example which should make it clear.
Basically I want to use a variable to determine what cell I have to use.
For example, I count the amount of rows my sheet has and store it in a variable. Now I want to use that variable to determine a range.
Range("K2:M*").Select
Now where I have the * I want to use the rows I counted and stored in a variable earlier on.
How can I do this?

A better approach to such things is using the alternate form of Range's arguments, the one with cells. Why? because is really easier to dealing with numerically-indexed columns than the "A1" type of address. For example:
Dim col1 As Long
Dim row1 As Long
Dim col2 As Long
Dim row2 As Long
' Some code to initialize/calculate
Let col1 = 11 'K
Let row1 = 2
Let col2 = 13 'M
Let row2 = SomeFunctionThatCalculates()
With Worksheets("Whatever") ' Replace with a valid Worksheet object
Call .Range( _
.Cells(row1,col1), _
.Cells(row2,col2) _
).Select
End With
Of course, for rows a quick way is the one given by Rory in comments.

It's simple:
sub Test()
Dim Var1 as string
Var1 = 'Whatever your variable is
Range("K2:M" & Var1).select
End sub

I think your question was to how to get the range of the worksheet selected with the ability to scale to the bottom of the sheet, excluding headers - thus starting with 2:bottom. i tend to use the usedrange property.
sub test
dim rowcount as double
rowcount = activesheet.usedrange.rows.count
Range("K2:M" & rowcount).Select
end sub

Related

VBA concatenate two ranges and create new range in VBA

Is it possible to create a new range that concatenates the 3 ranges together into a new range? For example, the first value of the range would be The-Ball-Park and the second value would be The-Train-Station, so on and so forth over X amount of rows. If possible, I would like it so script would skip over completely blank rows.
I would like to save the range into a variable, I would Not like to have the range be inserted in the sheet.
Thank you!
Key1
Key2
Key3
The
Ball
Park
The
Train
Station
The
Fast
Lane
You might need to make it a bit more clever if you don't intend on using exactly 3 inputs for each output.
Let me know.
Option Explicit
Option Base 1
Sub ConcatRangeToArray()
'Variables
Dim I As Integer
Dim OG_Array
Dim Output_Array
Dim RG As Range
'Set this to whatever range you need concatenated
Set RG = Sheet1.Range("A2:C4") '<<< range to concatenate
OG_Array = RG
ReDim Output_Array(1 To UBound(OG_Array, 1))
'Preform concatenation
For I = 1 To UBound(OG_Array, 1)
Output_Array(I) = OG_Array(I, 1) & "-" & OG_Array(I, 2) & "-" & OG_Array(I, 3)
Debug.Print Output_Array(I)
Next I
End Sub
Example of spreadsheet I used:
Example of output:

Excel VBA verify if all fields in a column in a table are filled before saving

I am having troubles with a VBA code I want to write. I have looked through different questions here and in other forums but I cant find something that will help my needs.
My problem is about a table named "TableLaw", with about 43 columns and over 10000 rows.
Practically, my need can be divided in two parts:
Verify all fields in column [Comments] from TableLaw. Meaning, I want to see if all data fields in that column are not empty. So I will need to check over 10000 rows. Please note: the fields I am verifying have a formula in them, so they are not really empty. The formula concatenates some cells to form a comment. I need to see if there is a comment or not in each cell
If there are empty fields in the column [Comments], I want to block the workbook from saving. I would like to also highlight the cells that are 'empty' in the column to help the user see which field in the column he needs to work on.
I have no problems with the blocking from saving part, but I am having serious trouble with even forming a For Each or something that will iterate from cell to cell in the column [Comment] checking if the cell is empty or it has a formula only and highlight those cells which are empty.
It is important to use structure names like [Comments] because the user might add new columns to the table.
Thanks, and sorry for the trouble. I am relatively new to VBA and my prior knowledge in programming is few.
I have seen lots of complicated code snippets that I just can not understand, but I got this and I am sure all of you will laugh at my incompetence and doubt if I really did something:
Sub TableTest()
Dim tbl As ListObject
Dim tRows As Long
Dim tCols As Long
Dim lo As ListObject
Dim ws As Worksheet
Dim lr As ListRow
Dim lc As ListColumn
'I used this to get the column number and then use it in a For cycle to go through all cells in the column
col = WorksheetFunction.Match("COMMENTS", Sheets("Orders").Range("5:5"), 0)
Set tbl = ActiveSheet.ListObjects("TableLaw")
With tbl.DataBodyRange
tRows = .Rows.Count
tCols = .Columns.Count
End With
Set ws = ThisWorkbook.Worksheets("Orders")
Set lo = ws.ListObjects("TableLaw")
For Each lr In lo.ListRows
Cells(lr, col).Interior.ColorIndex = 37
Next lr
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'I added the range like this because I do not know how to add the column name.
If WorksheetFunction.CountA(Worksheets("Orders").Range("AM6:AM10500")) <> "" Then
MsgBox "Workbook will not be saved unless all comments are added"
Cancel = True
End If
End Sub
You can check it with the .Value function
ie.
If (Range("A1").Value = "") Then
''' PROCESS CODE
End If

Match Function in Specific Column Excel VBA

I'm trying to write a program in VBA for Excel 2011 that can search a column (which column that is is determined by another variable) for the number 1 so that it knows where to start an iteration.
Say that the number of the column is given by colnumvar. The only way I can think of is the Match function, which led me to write the following:
Dim rowvar As Integer
rowvar = WorksheetFunction.Match(1,Range(Cells(1,colnumvar),Cells(1000,colnumvar)),0)
This gave me an error, however. After playing around with it some more, I realized that it must not accept the Cells([row],[col]) way of doing it, but rather wants something like Range("A1:A100"). Unfortunately, I can't do it that way, since the program is figuring out what column to look in. Any help for figuring out how to get past this would be greatly appreciated!
What you mean to do is better served with Range.Find.
Dim rngtrg As Range, rngsrc As Range
Dim ws As Worksheet
Set ws = ActiveSheet
Set rngsrc = ws.Range(ws.Cells(1,colnumvar),ws.Cells(1000,colnumvar))
Set rngtrg = rngsrc.Find(1,...)
rowvar = rngtrg.Row
this easy function retreive the positoin of that you find
Function rowvar(ByRef c As Integer) As Integer
Dim keySrc As Integer
keySrc = 22 'wath you want to find
rowvar = WorksheetFunction.Match(keySrc, Range(Cells(1, c), Cells(1000, c)), 0)
End Function
use with rowvar(x)

Excel - Variable in Range

The variable tablelength counts how many items are in a table of mine. I want to select my entire table, but it varies in sizes so my range has to include a variable. I've googled a lot and searched this site (Using variables in Excel range <- that method looked promising but didn't work). Below is a snippet of my code, but includes everything that is relevant.
Private Sub CommandButton1_Click()
Dim shSource As Worksheet
Dim shDest As Worksheet
Dim tablelength As Integer
Set shDest = ThisWorkbook.Sheets("Sheet2")
'here comes some code that determines the value of tablelength, which is 8 in this case
shDest.Range("L" & "4" & ":" & "M" & tablelength).Select
End Sub
I appreciate the help.
edit: the debugger highlights the shDest.Range code.
Unless you need tablelength variable somewhere else in the code, you could try using:
shDest.Range("L4").CurrentRegion.Select
CurrentRegion.Select will select all cells starting from "L4" until it reaches a blank row and column, so providing your tables are surrounded by blank cells this should select the whole table regardless of the size
Here you go, try this:
ActiveSheet.Range(Cells(2, 3), Cells(10, 4)).Select
Taken from http://support.microsoft.com/kb/291308
The first parameter to Cells is the row and the second is the column as a number.
So for you it would look something like this:
shDest.Range(Cells(4, 12), Cells(tablelength, 13)).Select
If it's a proper Table on the spreadsheet, and not just cells formatted to look like a table, you can directly refer to the 'live' size of the table in your code without jumping through all these hoops.
In your VBA code,
The 'Table' is referred to as a ListObject
You can declare a new ListObject, and look up its DataBodyRange.Rows.Count
This should work:
Sub MyMacro()
Dim Tabl As ListObject
Set Tabl = Worksheets("Sheet1").ListObjects("Table1")
MsgBox Tabl.DataBodyRange.Rows.Count
End Sub
You can also set a range variable to refer to the 'Data' range. You need to use the following code.
Dim Rng As Range
Set Rng = Worksheets("Sheet1").ListObjects("Table1").DataBodyRange
Now Rng.Cell(1,1) or Rng.Range("A1") refers to the top left cell of the data body and so on and so forth...

Problems with VLOOKUP in VBA

All,
I'm trying to use vlookup in a simple VBA function, but it is continually returning #VALUE!
Here is the code:
Public Function getAreaName(UBR As Integer) As String
Dim result As String
Dim sheet As Worksheet
Set sheet = ActiveWorkbook.Sheets("UBR Report")
' check level 3 then 2 then 4 then 5
result = Application.WorksheetFunction.VLookup(UBR, sheet.Range("UBRLookup"), Application.WorksheetFunction.Column(sheet.Range("UBRLookup[Level 3]")), False)
getAreaName = result
End Function
Any thoughts?
I'm not quite sure what you're trying to do with the "UBRLookup[Level 3]" reference, but as Joseph has pointed out, that's the bit that you're doing wrong.
[ is not a valid character for a named range in Excel.
The column that you're referencing needs to be a numeric value, the offset from the start of the table-array you've defined as your named range.
The below should work, provided the column you want to pull out is the second column in your named range (e.g. what you're referring to as [level 3] is in the second column).
Public Function getAreaName(UBR As Integer) As String
Dim result As String
Dim sheet As Worksheet
Set sheet = ActiveWorkbook.Sheets("UBR Report")
result = Application.WorksheetFunction.VLookup(UBR, sheet.Range("UBRLookup"), 2, False)
getAreaName = result
End Function
Update:
I've had a look at Excel 2007 and from what I can see the column function isn't exposed as an Application.WorksheetFunction.
You can use it on the sheet with =Column(D4), but when trying to autocomplete within the vba editor, the function isn't there. This may be due to a difference in versions, so I'll ignore that for now.
It still definitely seems like you're mis-using the third argument. If you really don't want to use the number reference we need to find out where the function is going wrong.
A few tests along the lines of
Debug.Print Application.WorksheetFunction.Column(D4)
Debug.Print sheet.Range("UBRLookup[Level 3]")
should hopefully help to show you exactly where it's going wrong - I believe that it will object to both of the above, but if it returns some useful information then we may be a step closer to your solution.
Break you function up into more pieces. Then debug it and make sure every piece is set up the way you expect.
Example:
Public Function getAreaName(UBR As Integer) As String
Dim result As String
Dim sheet As Worksheet
Set sheet = ActiveWorkbook.Sheets("UBR Report")
Dim range as Range = sheet.Range("UBRLookup")
Dim column as Column = Application.WorksheetFunction
.Column(sheet.Range("UBRLookup[Level 3]"))
result = Application.WorksheetFunction.VLookup(UBR, range, column, False)
getAreaName = result
End Function
In fact, just by doing that I noticed something weird. You use a range in two different places, but in one place you're looking for UBRLookup, and in another you're looking for UBRLookup[Level 3], is that correct?
I am disturbed by
Dim column as Column =
Application.WorksheetFunction.Column(sheet.Range("UBRLookup[Level 3]"))
You should Dim column as long, I think, and maybe use a variable name that's not to be confused with a property, like lngCol.
This part: sheet.Range("UBRLookup[Level 3]") is suspect as "UBRLookup[Level 3]" is not a valid range name.