Using for each with a worksheet reference - excel

If ws below has both the range object and cell property:
dim ws as worksheet
set ws = sheets("sheet_1")
x = ws.range("A1")
x = ws.cells(1,1)
Why doesn't this work:
dim cel as range
dim rng as range
set rng = 'some range
for each cel in rng
ws.cel.value = "foo"
next
I want to ensure the right sheet is being referenced, and it seems logical to use ws as part of the cel reference to ensure the sheets reference is explicit.

You need to include how you set the rng, that's a vital bit of info to help troubleshoot. But generally, this should work:
Sub t()
Dim ws As Worksheet
Set ws = Sheets("sheet_1")
Dim cel As Range, rng As Range
Set rng = ws.Range("A1:C100")
For Each cel In rng.Cells
cel.Value = "foo"
Next
End Sub

Related

VBA Adding another variable to a loop

I have a method CreatePage(). I would like to loop through variables to pass through the method. I have managed to get it working for one variable:
Sub main()
Dim rng As Range
Dim aSht As Worksheet
Set aSht = ThisWorkbook.Sheets("Sheet1")
For Each rng In aSht.Range("A5:A8")
CreatePage(rng)
Next rng
End Sub
I need it to loop as follows:
CreatePage("A5", "C6")
CreatePage("A6", "C7")
CreatePage("A7", "C8"), ...
I am stuck on how to pass through two variables. This is where I have got so far, but I don't think I'm going in the right direction:
Sub main()
Dim rng As Range
Dim rng2 As Range
Dim aSht As Worksheet
Dim bSht As Worksheet
Set aSht = ThisWorkbook.Sheets("Sheet1")
Set bSht = ThisWorkbook.Sheets("Sheet2")
For Each rng In aSht.Range("A5:A8")
For Each rng2 In bSht.Range("C6:C9")
CreatePage(rng,rng2)
Next rng, rng2
End Sub
I have adjusted CreatePage() to hold two variables. I'm puzzled on getting the second variable in the for loop. Can anyone help out?
A nested for loop won't help here. You need to loop one range only and pick the required cell from the other
Sub main()
Dim rng As Range
Dim rng2 As Range
Dim aSht As Worksheet
Dim bSht As Worksheet
Set aSht = ThisWorkbook.Sheets("Sheet1")
Set bSht = ThisWorkbook.Sheets("Sheet2")
Dim idx As Long
Set rng = aSht.Range("A5:A8")
Set rng2 = bSht.Range("C6:C9")
'You might want to add code here to check the size and shape of your ranges
For idx = 1 To rng.Cells.Count
CreatePage rng.Cells(idx), rng2.Cells(idx)
Next
End Sub
Just a simple change needed.
For Each rng In aSht.Range("A5:A8")
For Each rng2 In bSht.Range("C6:C9")
CreatePage rng, rng2
Next rng2
Next rng

Filtered Row Count

In VBA, I wish to find the row count of a filtered column, so I wrote VBA code as
FilteredRowCount = ActiveSheet.UsedRange.SpecialCells(xlCellTypeVisible).Rows.Count
But FilteredRowCount always return value of 1, what would cause this?
Do like this
Sub test()
Dim Ws As Worksheet
Dim rngDB As Range
Dim r As Integer
Dim rng As Range
Set Ws = ActiveSheet
Set rngDB = Ws.UsedRange.SpecialCells(xlCellTypeVisible)
For Each rng In rngDB.Areas
r = r + rng.Rows.Count
Next rng
MsgBox r
End Sub

Apply formatting to a range using array loop - VBA

Using VBA i make to:
Set two ranges
Create an array of all ranges names
Loop the array in order to apply formatting to each range in the array
BUT on line .Interior.Color = vbRed
i receive the below error:
Run-time error '424': Object required
Code
Sub test()
Dim rng1 As Range, rng2 As Range
Dim strRanges As Variant
Dim i As Long
Set rng1 = Sheet1.Range("A1:D1")
Set rng2 = Sheet2.Range("C5:H5")
strRanges = Split("rng1,rng2", ",")
For i = LBound(strRanges) To UBound(strRanges)
With strRanges(i)
.Interior.Color = vbRed
End With
Next i
End Sub
i have already use:
With Range(strRanges(i))
instead of:
With strRanges(i)
without any luck!
Any help will appreciate.
You can do this in just one line if the ranges are in the same worksheet
Sheet1.Range("A1:D1,C5:H5").Interior.Color = vbRed
You can use union if the ranges are in the same worksheet
Dim rng1 As Range, rng2 As Range
Set rng1 = Sheet1.Range("A1:D1")
Set rng2 = Sheet1.Range("C5:H5")
Union(rng1, rng2).Interior.Color = vbRed
You can use real arrays for your ranges if they are in different worksheets
Sub test()
Dim rng(1 To 2) As Range
Set rng(1) = Sheet1.Range("A1:D1")
Set rng(2) = Sheet2.Range("C5:H5")
Dim i As Long
For i = LBound(rng) To UBound(rng)
With rng(i)
.Interior.Color = vbRed
End With
Next i
End Sub
If you don't have numbered range variable names then you can use another array:
Sub test()
Dim rngABC As Range, rngXYZ As Range
Set rngABC = Sheet1.Range("A1:D1")
Set rngXYZ = Sheet1.Range("C5:H5")
Dim ArrRng() As Variant
ArrRng = Array(rngABC, rngXYZ)
Dim rng As Variant
For Each rng In ArrRng
rng.Interior.Color = vbRed
Next rng
End Sub
Note that if you think you have to use numbered variable names like
Dim rng1 As Range, rng2 As Range
this always is a clear sign for using an array instead:
Dim rng(1 To 2) As Range
numbered variable names are a bad practice. Always choose meaningful names.

Loop through worksheets and copy value to range

I'm trying to loop through all worksheets (except the first two), copying a value from each one, and then placing the copied value into a column. This is what I have so far. It isn't giving me an error message, but it's also not working.
Sub copyGrades()
Dim ws As Excel.Worksheet
Dim grade As Double
Dim rng As Range
Dim rcell As Range
Set rng = ThisWorkbook.Worksheets("Student List").Range("H2:H174")
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "Rubric" And ws.Name <> "Student List" Then
grade = ws.Range("E11").Value
For Each rcell In rng.Cells
rcell.Value = grade
Next rcell
End If
Next ws
End Sub
I couldn't get the nested loops to work, but I was able to solve it using another method (looking for a match between the worksheet name and the values in a given column).
Sub copyGrades()
Dim ws As Excel.Worksheet
Dim rng As Range
Dim rcell As Range
Set rng = ThisWorkbook.Worksheets("Student List").Range("F2:F174")
For Each rcell In rng.Cells
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = rcell.Value Then
rcell.Offset(0, 3).Value = ws.Range("E11").Value
End If
Next ws
Next rcell
End Sub
I think this is how I would do it (surely not the only way):
Option Explicit
Sub copyGrades()
Dim ws As Excel.Worksheet
Dim grade As Double
Dim rng As Range
Dim count As Integer
count = 1
Set rng = ThisWorkbook.Worksheets("Student List").Range("H2:H174")
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "Rubric" And ws.Name <> "Student List" Then
grade = ws.Range("E11").Value
rng.Cells(count, 1) = grade
count = count + 1
End If
Next
End Sub

finding out what is the range with Endxl

First get the range of non-empty cells from Source workbook. Then select similar range of cells in Destination Workbook. How can this be achieved?
Full Code::
~~~~~~~~~~~
Public Sub ConvertTo_K()
Dim rng1 As Range
Dim rng2 As Range
Set rng1 = Workbooks("Source.xls").Worksheets("Source").Range(Cells(2, "A"), Cells(Rows.Count, "A").End(xlUp).Resize(, 1))
Set rng2 = Workbooks("Destination.xls").Worksheets("Destination").Range(rng1.Address)
rng2.Value = Round(rng1.Value / 1000, 2)
'At this point, an error message of Type Mismatch pops up (Due to different ranges of rng1 and rng2). Do i have to use a loop? How to do that?
End Sub
Round(rng1.Value / 1000, 2) will not work because rng1 is a collection of ranges and can be accessed by rng1.Cells(1).value
rng1.Value is not valid.
You may loop thru each cell of rng2 and apply the round formula.
Public Sub ConvertTo_K()
Dim rng1 As Range
Dim rng2 As Range
Dim RoundRange As Range
Dim rngVal As Double
Dim SourceWkb As Workbook
Set SourceWkb = Workbooks("Source.xls")
Dim SourceSht As Worksheet
Set SourceSht = SourceWkb.Worksheets("Source")
With SourceSht
Set rng1 = .Range(.Cells(2, "A"), .Cells(.Rows.Count, "A").End(xlUp).Resize(, 1))
End With
Dim DestinWkb As Workbook
Set DestinWkb = ThisWorkbook 'Workbooks("Destination.xls")
Dim DestinSht As Worksheet
Set DestinSht = DestinWkb.Worksheets("Destination")
With DestinSht
Set rng2 = .Range(rng1.Address)
End With
'rng2.Value = Round(rng1.Value / 1000, 2) This wont work
rng1.Copy rng2
For Each cell In rng2
cell.Value = Round(cell / 1000, 2)
Next
End Sub
If your rng1 works fine you could do it this way:
set rng2 = Workbooks("Destination.xls").Worksheets("Destination").Range(rng1.address)

Resources