VBA Looping through an IF Statement - vba

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

Related

Counting Rows Using a Loop in VBA?

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

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

excel VBA code to Copy and Paste a set of data with a finite amount (count)

In excel on a single sheet, I have a blank template and a set of raw data on the side which needs to be inserted into the template. I need help creating the VBA code to copy and paste the data into the template with it not pasting any extra cells (stop at the end of the data). My raw data changes and should be able to be any length of rows but it is always constant from columns Z:AL. I am interesting in moving it to columns A5:M5.
Thanks in advance!
This is the simplest code I can think of. You might want to throw a worksheet reference in front of the Range and I included a couple of methods of finding the end of the range. I prefer the 3rd method.
dest = "A5"
wsName = "DataSheet"
With Worksheets(wsName)
endRow1 = .Range("Z1").End(xlDown).Row
endRow2 = .Range("Z105000").End(xlUp).Row
endRow3 = .Range("Z:AL").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
.Range("Z1:AL" & endRow3).Copy Destination:=Range(dest)
End With
If there are not blanks in a column in the dataset (I assume column Z) then you can use Range.End to get the last row. I try to avoid using Copy/Paste in macros, because there's a faster way to do it.
Option Explicit
Sub MoveDataRange()
Dim dest As Range, endRow As Integer
With Worksheets("DataSheet")
endRow = .Range("Z1").End(xlDown).Row
Set dest = .Range("A5").Resize(endRow, 13) '13 columns between Z:AL
dest.Value = .Range("Z1:AL" & endRow).Value
End With
End Sub

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...

Excel 2010 VBA to copy tab names to consecutive columns

I am trying to build quite a complex excel macro based on dynamic data. My first stumbling block is that i am struggling to get a button-triggered Excel macro to take name of each tab after the current one and insert its name every third column of the current sheet
I have:
Sub Macro1()
On Error Resume Next
For Each s In ActiveWorkbook.Worksheets
Sheet2.Range("A1:ZZ1").Value = s.Name
Next s
End Sub
This really does not work well, as it simply seems to enter the name of the last sheet all the way between A1 and ZZ1! what am I doing wrong?
This will put the names of worksheets in the tabs to the right of the Activesheet in every 3rd column of row 1 of the Activeshseet:
Sub Macro1()
Dim i As Long
With ThisWorkbook
'exit if Activesheet is the last tab
If .ActiveSheet.Index + 1 > .Worksheets.Count Then
Exit Sub
End If
For i = .ActiveSheet.Index + 1 To .Worksheets.Count
.ActiveSheet.Cells(1, (i - .ActiveSheet.Index) + (((i - .ActiveSheet.Index) - 1) * 2)) = .Worksheets(i).Name
Next i
End With
End Sub
Please note that it's a bad idea to useOn Error Resume Next in the general manner that you did in your original code. It can mistakenly mask other errors that you don't expect. It should just be used to catch errors that you do expect.