I know how to count rows (and display the result in the form of a message form) using this syntax:
Sub CountRows1()
Dim last_row As Long
last_row = Cells(Rows.Count, 1).End(xlUp).Row
MsgBox (last_row)
End Sub
I was wondering if there's another way to do it without declaring variables and instead, by selecting a range and then using offset.
I was thinking something along the lines of the follow, but no idea where to go from here:
Sub UseLoop ()
Range ("A1").Select
Do Until Active.Cell.Value = ""
-- Something to do the counting, can't seem to get this part right
ActiveCell.Offset (1,0).Select
Loop
End Sub
Related
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
I am a beginner. I have been trying to teach myself VBA and researching this question for two weeks, including reviewing all the relevant answers on this forum. I give up!
I am trying to loop through the rows of a table to select a table row based on the content of one of the row's cells (naming a particular column). I want to use the name of the table column. But something is wrong with my "If ... Then" statement. I get errors with every attempt. Right now I get a compile error "Expected Then or Go To," with the period before Value highlighted. But I have a feeling that if I fixed that error there would be another one right behind it. What am I getting wrong, besides trying to learn this on my own? ;>)
Thanks in advance!
Sub CommandButton1_Click()
Dim tbl As ListObject
Dim x As Long
Set tbl = ActiveSheet.ListObjects("Table1")
For x = 1 To tbl.Range.Rows.Count
If (Range("Table1[Status]")).Value = "Completed"
'I can't seem to find the right statement to put between If and .Value!
Rows(x).Select
End If
Next x
End Sub
Change If (Range("Table1[Status]")).Value = "Completed" to If (Range("Table1[Status]").Value) = "Completed" Then. Your .Value just needed to be put in the brackets. I would also highly suggest looking into the Rubberduck add-in for VBA. It has an Auto Indenter so your code always looks in order.
Sub CommandButton1_Click()
Dim tbl As ListObject
Dim x As Long
Dim myRange As Range
Set tbl = ActiveSheet.ListObjects("Table1")
For x = 1 To tbl.Range.Rows.Count
If tbl.DataBodyRange(x, Range("Table1[Status]").Column) = "Completed" Then
If myRange Is Nothing Then
Set myRange = tbl.ListRows(x).Range
Else
Set myRange = Union(myRange, tbl.ListRows(x).Range)
End If
End If
Next x
myRange.Select
End Sub
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...
Kind of new to VBA programming but need it to complete a project.
I'm basically trying to copy and paste cells based on an IF Statement and would like to do this on a cell-by-cell basis so I incorporated a loop. The code looks like the following below. What ends up happening is that the first line is copied/pasted just fine but the loop does not continue. When I use debug.print i , the only number that is populated is 6. I've also tried a For Statement but that ends up behaving the same way. Any ideas?
Private sub Copy_Dates()
Dim i as Integer
i =6
Do
If Cells(i,79)= 1 then
Sheets("Tracking").Select
Range(Cells(i,106),Cells(i,108)).Copy
Sheets("Tr_Tracking").Select
Range(Cells(i_25003,2),cells(i+25003,4)).PasteSpecial Paste:=xlPasteValues
End if
i= i+1
Loop while i < 10
End sub
EDIT:
So I've realized that the code that i wanted is not going to be very helpful to my project anymore. What I really need is a method to select non consecutive cells based on a criteria, and then copy those cells to another worksheet as a single block.
So, taking from the above code, I need to make sure to select
.range(.cells(i,106,.cells(i,108))
only when the following condition is met:
if .cells(i,79)=1
then imagine that i would have some array of selected cells based on this condition and then i would be able to paste it to the second sheet defined above wsO=thisworkbook.sheets("TR_Tracking").
I hope that makes sense and hopefully not too complicated of logic.
EDIT:EDIT:
I was able to figure this one out. I used the following code below to accomplish the edit section above.
Private Sub SelectArray_andCopy()
Dim FinalSelection as Range
Sheets("Tracking").Select
Cells(2,79).Select
For each c in intersect(activesheet.usedrange,range("CA6:CA500"))
if c.value=1 then
if finalselection is nothing then
set finalselection=range(cells(c.row,106),cells(c.row,108))
else
set finalselection = union(finalselection, range(cells(c.row,106,cells(c.row,108)))
end if
end if
next c
if not finalselection is nothing then finalselection.select
Selection.copy
Sheets("TR_Tracking").Select
Range("b250009,d26000").PasteSpecial Paste:=xlPasteValues
The problem is that you are using .Select and hence the focus is changing. Also your cells objects are not fully qualified.
INTERESTING READ
Further i_25003 is incorrect. I guess you meant i + 25003
Try this (UNTESTED)
Private Sub Copy_Dates()
Dim wsI As Worksheet, wsO As Worksheet
Dim i As Long
Set wsI = ThisWorkbook.Sheets("Tracking")
Set wsO = ThisWorkbook.Sheets("Tr_Tracking")
For i = 6 To 9
With wsI
If .Cells(i, 79) = 1 Then
wsO.Range(wsO.Cells(i + 25003, 2), wsO.Cells(i + 25003, 4)).Value = _
.Range(.Cells(i, 106), .Cells(i, 108)).Value
End If
End With
Next i
End Sub
Within Excel, I use tables to store dynamic data inside a seperate worksheet. Entering new data works like a charm, however, I would like to be able to dynamically retrieve a single row from that table and store its data in variables. I would prefer to build a function so I could do something like this:
findFromCatsByDate(searchterm) 'returns a single row if found with mathing date.
Note that the table is dynamic and not a fixed range (so it changes vertically). I want to reuse this function with slight modification on other tables. I kind of need an example how to achieve this in VBA.
Thanks,
This will return a reference the row that matches Key in a specified table
Function GetRow(TableName As String, ColumnNum As Long, Key As Variant) As Range
On Error Resume Next
Set GetRow = Range(TableName) _
.Rows(WorksheetFunction.Match(Key, Range(TableName).Columns(ColumnNum), 0))
If Err.Number <> 0 Then
Err.Clear
Set GetRow = Nothing
End If
End Function
Example use
Sub zx()
Dim r As Range
Set r = GetRow("MyTable", 1, 2)
If Not r Is Nothing Then
r.Select
End If
End Sub