I am currently trying to develop that:
First, using a loop populates the numbers 0 to 1500 each like 8 columns apart, and then using another to loop to populate values from another worksheet but I want to use offset and so the numbers 0 to 1500 are the number of rows I want to offset each time. So 0 rows,1 row,2 rows etc.
I am trying to absolutely reference the column from which I will be offsetting the values on the other sheet (which is called DEX Spread Report (Corp)). However, I am having trouble absolutely referencing the column (Column D row 7) as I am not familiar with VBA's method.
Help would be much appreciated! Thanks
Sub Output_Numbers_For_Purpose_of_Offsetting_From_DexCorp()
Dim i As Integer
Dim m As Integer
Sheets("Sheet1").Select
Range("B1").Select
For i = 0 To 1500
ActiveCell.Value = i
ActiveCell.Offset(0, 8).Select
Next i
Range("B1").Select
For m = 0 To 1500
If ActiveCell.Value = m Then
ActiveCell.Offset(1, 0).Value = "=Offset('DEX Spread Report (Corp)'! (Range("D7").FormulaR1C1 = "C[0]*10"), m, 0)
Else: ActiveCell.Offset(1, 0).Value = ""
End If
ActiveCell.Offset(8, 0).Select
Next m
End Sub
EDIT - Incorporate Code from comments
I am getting an issue at:
ActiveCell.Offset(1, 0).Value = "=Offset('DEX Spread Report (Corp)'! (Range("D7").FormulaR1C1 = "C[0]*10"), m, 0)
I am trying to structure it as:
ActiveCell.Offset(1, 0).Value = Offset('DEX Spread Report (Corp)'!$D7,m,0 )
One way:
Dim r As Range
For Each r In Range("B1:B1000")
If r.Value = m Then
'stuff
Else
'stuff
End If
Next r
Another way:
Dim r As Range
Set r = Range("B1")
For m = 1 To 1500
If r(m, 1).Value = m Then
'stuff
Else
'something else
End If
Next m
If I'm following you correctly, you seem to be trying to get your formula to offset the $D7 reference as if you had manually pasted it into B2 and copied it across the worksheet.
I'll offer an alternative solution, since you seem to know that you'll always want to offset by 8 rows. Rather than deal with however VBA wants to absolute cell references, why not just calculate the row number? (m * 8) + 7 will give you $D7 at 0, $D15 for 1, and so on.
Sub Output_Numbers_For_Purpose_of_Offsetting_From_DexCorp()
Dim i As Integer
Dim m As Integer
Sheets("Sheet1").Select
Range("B1").Select
For i = 0 To 1500
ActiveCell.Value = i
ActiveCell.Offset(0, 8).Select
Next i
Range("B1").Select
For m = 0 To 1500
If ActiveCell.Value = m Then
ActiveCell.Offset(1, 0).Value = "=Offset('DEX Spread Report (Corp)'!$D" & (m * 8) + 7 & "," & m & ", 0)"
Else: ActiveCell.Offset(1, 0).Value = ""
End If
ActiveCell.Offset(0, 8).Select
Next m
End Sub
quite hard to follow your code
maybe you were for this:
Option Explicit
Sub Output_Numbers_For_Purpose_of_Offsetting_From_DexCorp()
Dim i As Long
With Sheets("Sheet1")
For i = 0 To 1500
.Range("B1").Offset(, i * 8) = i
Next i
For i = 0 To 1500
With .Range("B1").Offset(i * 8)
If .Value = i Then
.Offset(1, 0).Value = Worksheets("DEX Spread Report (Corp)").Range("D7").Offset(i + 6)
Else
.Offset(1, 0).Value = ""
End If
End With
Next i
End With
End Sub
Related
I'm trying to clean up raw data exported from an online database.
There can be up to five columns. If all cells in a row have a value of 0, I want to delete that row.
When the user exports the data, they can choose to exclude columns, and the columns can be in any order.
For example, if the data contains only two of the possible five columns, I want to check just those two for 0s.
Could do a a big loop looking at every row and seeing if all 5 columns in that row are blank
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("sheetname")
Dim LastRow As Integer
LastRow = sh.UsedRange.Rows.Count - 1
For i = 1 To LastRow
If (sh.Cells(i, 1).Value = "" And sh.Cells(i, 2).Value = "" And sh.Cells(i, 3).Value = "" And _
sh.Cells(i, 4).Value = "" And sh.Cells(i, 5).Value = "") Then
sh.Cells(i, 1).EntireRow.Delete
i = i - 1
Dim newLastRow As Integer
newLastRow = sh.UsedRange.Rows.Count - 1
If i = newLastRow Then
Exit For
End If
End If
Next i
MsgBox ("Done")
End Sub
#kyle campbell, thank you for your input! It didn't quite get me there, but it did get my wheels turning. Here is the solution I came up with, if anyone's curious:
I set a variable to represent the column number for each of the 5 possible columns using Range.Find. If the Find came up with nothing, I set the variable to 49, since the maximum number of columns this report can have is 48.
Then I did a nested If to test if the value in each cell was either 0 or null (because if the column number is 49, there won't be any data there). If all Ifs were true, I deleted the row. I also added a counter and message box, just to make sure this worked.
Sub DeleteRows()
Dim O As Long
Dim E As Long
Dim H As Long
Dim B As Long
Dim P As Long
lRow = Range("A1").CurrentRegion.Rows.Count
If Range("1:1").Find("SUM(OBLIGATIONS)") Is Nothing Then
O = 49
Else
O = Range("1:1").Find("SUM(OBLIGATIONS)").Column
End If
If Range("1:1").Find("SUM(EXPENDITURES)") Is Nothing Then
E = 49
Else
E = Range("1:1").Find("SUM(EXPENDITURES)").Column
End If
If Range("1:1").Find("SUM(HOURS)") Is Nothing Then
H = 49
Else
H = Range("1:1").Find("SUM(HOURS)").Column
End If
If Range("1:1").Find("SUM(BUDGET_RESOURCES)") Is Nothing Then
B = 49
Else
B = Range("1:1").Find("SUM(BUDGET_RESOURCES)").Column
End If
If Range("1:1").Find("SUM(PRIOR_YEAR_RECOVERY)") Is Nothing Then
P = 49
Else
P = Range("1:1").Find("SUM(PRIOR_YEAR_RECOVERY)").Column
End If
Dim j As Integer
j = 0
For i = lRow To 2 Step -1
If Cells(i, O) = 0 Or Cells(i, O) = "" Then
If Cells(i, E) = 0 Or Cells(i, E) = "" Then
If Cells(i, H) = 0 Or Cells(i, H) = "" Then
If Cells(i, B) = 0 Or Cells(i, B) = "" Then
If Cells(i, P) = 0 Or Cells(i, P) = "" Then
Rows(i).Delete
j = j + 1
End If
End If
End If
End If
End If
Next i
MsgBox "Macro complete, " & j & " lines deleted."
End Sub
New member here trying to fathom what might be wrong with the following code...
I am trying to copy rows from "A5" to the last row and columns A:L except columns "C & D" when C = "Y" but not getting anything when execute Macro and debug now giving much away (although I am new to this :-)). Any ideas or help would be appreciated.
Private Sub UpdateImportFile_Click()
Dim count As Long
count = WorksheetFunction.CountA(Range("A5", Range("A5").End(xlDown)))
For i = 5 To count
If Worksheets("Case Entry").Cells(i, 3).Value = "Y" Then
Worksheets("Case Entry").Rows(i).Columns(1, 2).Copy
Worksheets("Import File").Activate
Worksheets("Import File").Cells("A2").Select
ActiveSheet.PasteSpecial xlPasteValues
End If
Next
Application.CutCopyMode = False
ThisWorkbook.Worksheets("Case Entry").Cells(1, 1).Select
End Sub
Try this:
Private Sub UpdateImportFile_Click()
Dim count As Long
count = WorksheetFunction.CountA(Range("A5", Range("A5").End(xlDown)))
With Worksheets("Case Entry")
For i = 5 To count + 4
If .Cells(i, 3).Value = "Y" Then
Worksheets("Import File").Cells(i, 1).Resize(1, 2).Value = .Cells(i, 1).Resize(1, 2).Value
End If
Next
End With
End Sub
Range("A4:A29").Select
Selection.ClearContents
Range("A34:A59").Select
Selection.ClearContents
Range("A64:A89").Select
Selection.ClearContents
Range("A94:A119").Select
Selection.ClearContents
Range("A124:A149").Select
Selection.ClearContents
Range("A154:A179").Select
Selection.ClearContents
Range("A184:A209").Select
Selection.ClearContents
Range("A1").Select
I did the above coding to clear some boxes in excel, but it does not give me flexibility over range of boxes, what I want is to clear out any filled boxes in column A but if x mod 30 equals to zero to skip the next 3 and so on. I have used a similar code to fill up the boxes, see below:
With RegExp
.Pattern = "\bT[0-9A-Z\(\)\-]+"
.Global = True
.IgnoreCase = False
Set matches = .Execute(txt)
End With
For Each Match In matches
If x Mod 30 = 0 Then
x = x + 4
End If
Cells(x, 1) = Match
x = x + 1
Cells(x, 1) = Match
If x Mod 30 <> 0 Then
x = x + 1
End If
Next
If anyone could help me that would be great! Thanks
It's a bad idea (performance-wise) to first select the cell and then use Selection.ClearContents
Try this principle:
Range(Cells(x, 1), Cells(x + 29, 1)) = ""
This clears the contents of all Cells between x,1 and x+29,1
For your purpose it might be something like this (you might have to tweek the details because they are not clear from your post):
For x = 0 to 9 ' repeat however many times you want
startingRow = x * 33 + 1
Range(Cells(startingRow, 1), Cells(startingRow + 28, 1)) = ""
Next
I got it. Thanks #E.Villager
Private Sub CommandButton2_Click()
Dim lRow As Long
Dim lCol As Long
lRow = Cells(Rows.Count, 1).End(xlUp).Row
For x = 4 To lRow
If x Mod 30 = 0 Then
x = x + 4
End If
Cells(x, 1) = ""
Next
End Sub
I want to copy some values in a for-loop in VBA. Therefore I calculate the limits by:
For iCounter = 1 To (Range(...).End(xlDown).Row - Range(...).Row + 1)
Sadly Range(...).End(xlDown).Row returns 1048576. When I debug, suddenly the value changes to the right one. The same Code works well in some other locations in the VBA Code.
The main thing to keep in mind is that the End method reproduces in VBA the functionality of using Ctrl+Arrow Keys. These are meant to navigate between blocks of values.
Start at A1 here:
Hit Ctrl+Down:
This illustrates what happens when you use Ctrl+Down at the beginning or end of a block consisting of multiple cells -- you go to the end of that block. This is the case that you are implicitly referring to when you said that sometimes the code works well.
Now -- hit Ctrl+Down again:
You jumped to the next block. Now, do it again:
The bottom of that block. Finally, again:
Well -- there is no next block to go to -- so it goes all the way down. This corresponds to the case that strikes you as weird. It puts you here:
But -- something cool happens now: Press Ctrl + Up -- and Excel searches up for the next block:
And this is the last cell with data in column A.
For this reason -- you see the following code a lot in Excel VBA:
Cells(Rows.Count,1).End(xlUp)
To get the last used cell in a column (1 in this case) or the first cell in the column if the overall column is blank.
It's curious what you're saying about getting the right value when debugging. That makes me think that you may need to show more of your code. Anyway, doesn't matter, I just decided to have some fun with this. Here are multiple sample code snippets to do what you're asking about. Hope it gives you or anyone else interested some ideas about how to approach this problem because it is very common.
I'd definitely avoid using End(xlwhatever) on its own. It makes for non-robust code because it's too easy for values to get shuffled. It's not hard to just take the time to create a more elegant solution. You should be able to come up with something pretty robust by tailoring and combining the methods below for your particular use.
Sub CellLoop1()
'Colors cells from row i to last value in column
For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
Cells(i, 1).Interior.Color = RGB(0, 200, 0)
Next
End Sub
Sub CellLoop2()
'Colors cells from row i to end of continuous values or until row 100
Dim i As Integer
i = 1
Dim r As Range
Set r = Cells(i, 1)
Do Until r.Value2 = "" Or i > 100
r.Interior.Color = 123
i = i + 1
Set r = Cells(i, 1)
Loop
End Sub
Sub CellLoop3()
'Colors cells from row i until occurance of 5 continuous blanks
Dim i As Integer
i = 1
Dim r As Range
Set r = Cells(i, 1)
Dim BlankChain As Integer
Do Until BlankChain >= 5
r.Interior.Color = 123
If r.Value = Empty Then
BlankChain = BlankChain + 1
Else
BlankChain = 0
End If
i = i + 1
Set r = Cells(i, 1)
Loop
End Sub
Sub CellLoop4()
'Colors cells from row i until no value in sight (in next k number of rows)
Dim i, k, BlankCount As Integer
i = 1
k = 10
Dim r, SightRange As Range
Set r = Cells(i, 1)
Dim NoValueInSight As Boolean: NoValueInSight = False
Do Until NoValueInSight
Set SightRange = Range(r, r.Offset(k - 1, 0))
BlankCount = Application.WorksheetFunction.CountBlank(SightRange)
If BlankCount = SightRange.Rows.Count Then
NoValueInSight = True
Else
r.Interior.Color = RGB(255, 50, 255)
End If
i = i + 1
Set r = Cells(i, 1)
Loop
End Sub
Sub CellLoop5()
'Colors all values under range r (set as "A1")
Dim r, UnderRange As Range
Set r = Range("A3")
Set UnderRange = Range(r, Cells(Rows.Count, 1))
Dim i, n, BlankCount As Double: i = r.Row: n = 0
BlankCount = Application.WorksheetFunction.CountBlank(UnderRange)
Do Until n = (UnderRange.Rows.Count - BlankCount)
If Cells(i, 1) <> "" Then
n = n + 1
Cells(i, 1).Interior.Color = RGB(200, 200, 200)
End If
i = i + 1
Loop
End Sub
Sub CellLoop6()
'Colors all values under range r (set as "A1")
Dim r As Range
Set r = Range("A1")
If r.Value = "" Then Set r = r.End(xlDown)
Do Until r.Value = ""
r.Interior.Color = RGB(255, 100, 100)
If r.Offset(1, 0).Value <> "" Then
For i = r.Row To r.End(xlDown).Row
Cells(i, 1).Interior.Color = RGB(255, 100, 100)
Next
End If
Set r = r.End(xlDown)
Loop
End Sub
I am new to vba and I am attempting to create a module that takes the value in column C ( which should say "In Progress")and makes it "neutral" colored if the value within the same row on column E is less than 0.5(or 50%) but I have not had any luck. I have a counter variable made to keep track of the row I'm on. Any advice would be helpful and if you could recommend me to a good source for learning vba I would really appreciate it.
If Range("C1") = "Status" Then
Range("C1").Select
Do Until ActiveCell.Value = ""
If ActiveCell.Offset(1, 0).Value = "In Progress" Then
If Range("E" & counter).Value < 0.5 Then
ActiveCell.Offset(1, 0).Style = "Neutral"
End If
End If
ActiveCell.Offset(1, 0).Select
Columns("C").ColumnWidth = 13
counter = counter + 1
Loop
End If
End Sub
Untested:
Dim c As Range, sht As WorkSheet
Set sht = ActiveSheet
If sht.Range("C1").Value = "Status" Then
Set c = sht.Range("C2")
Do Until Len(c.Value) = 0
If c.Value = "In Progress" Then
If c.EntireRow.Cells(1, "E").Value < 0.5 Then
c.Style = "Neutral"
Else
c.Style = "Normal"
End If
End If
Set c = c.Offset(1, 0)
Loop
sht.Columns("C").ColumnWidth = 13
End If
As far as I understood your problem and this fits for you, you could try this. The following code searches for value "In Progress" in the entire column A, and if this value is found and the same row cell in column C is less than 0.5, then sets the color of the cell in column A to "no fill".
Sub searchValue()
Dim cell As Range
For Each cell In Worksheets(1).Columns(1).Cells
If cell = "In Progress" Then
If cell.Offset(0, 2) < 0.5 Then cell.Interior.ColorIndex = 0
End If
Next cell
End Sub