vba specialcells visible define range - vba

I am trying to use the SUM function to add all of the visible cells in column I from sRow to dRow (variables are starting and ending rows for a date range) but keep getting error 91 "object variable or with block variable not set" with this line of code:
vRange = Range("I" & sRow & ":" & "I" & Row).SpecialCells(xlCellTypeVisible)
I am not entirely sure why this throws an error because this works
visibleSum = Application.WorksheetFunction.Sum(Range("I" & sRow & ":" & "I" & dRow).SpecialCells(xlCellTypeVisible))
I am trying to get this block of code to return the sum of range "I, start date" to "I, end date" only counting positive numbers.
ActiveSheet.ListObjects("Table_Query_from_TCM95").Range.AutoFilter Field:=6, Criteria1:="10"
vRange = Range("I" & sRow & ":" & "I" & dRow).SpecialCells(xlCellTypeVisible)
visibleSum = Application.WorksheetFunction.Sum(vRange, ">0")
MsgBox (visibleSum)
EDIT - Thanks for the comments! both helped :D
Ultimately this counts hours each department worked where each department has its own number. 10, 20, etc. When I define my range for department 95, for the first week there are no cells which throws error 1004. That happens when the visible cells do not contain data for the date range specified. I attempted a couple different if statements this being one:
If Range("I" & sRow & ":" & "I" & dRow).SpecialCells(xlCellTypeVisible) Is Nothing Then
Else
Set vRange = Range("I" & sRow & ":" & "I" & dRow).SpecialCells(xlCellTypeVisible)
visibleSum = Application.WorksheetFunction.Subtotal(9, vRange)
MsgBox (visibleSum)
End If
Specifically this line
Set vRange = Range("I" & sRow & ":" & "I" & dRow).SpecialCells(xlCellTypeVisible)
gives error 1004 no cells found
I have 8 different Criteria that I have to iterate through. I am thinking about a select case but not sure if that will be efficient or actually accomplish what I need.
Any thoughts or tips are greatly appreciated!!
Thanks in advance!!

Related

Vlookup with Integer Variables

I am trying to do a Vlookup in my code and I have few integer variables. It gives me the error:
Run-time Error 1004
The code stops in the line of vlookup. All the variables have values. If someone can see where the problem, please let me know.
'Employees
empWS.Range("D1:G" & empLR).Copy
With tmpWB.Worksheets(2)
.Cells(1, 1).PasteSpecial xlPasteValues
.Range("$A$1:$D$" & empLR).AutoFilter Field:=1, Criteria1:=1
.Range("A2:D" & empLR).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.ShowAllData
empLR = .Cells(Rows.Count, "A").End(xlUp).Row
.Columns(1).Delete
.Range("D1").Value = "start date"
.Range("D2:D" & empLR).FormulaR1C1 = "=VLOOKUP(RC[-3],SAP!R1C1:R " & SLRow & " C70, StartColumn,0)" 'it stops here
.Columns("A:D").AutoFit
End With
"=VLOOKUP(RC[-3],SAP!R1C1:R " & SLRow & " C70," & StartColumn & ",0)"
You need to put startcolumn outside the speech marks
EDIT
"=VLOOKUP(RC[-3],SAP!R1C1:R" & SLRow & " C70," & StartColumn & ",0)"
(Patrick Honorez spotted that there was an extra space after R in the first bit)
Try removing extra spaces:
.Range("D2:D" & empLR).FormulaR1C1 = "=VLOOKUP(RC[-3],SAP!R1C1:R" & SLRow & "C70, StartColumn,0)"
Space in a range address is an intersection operator.

VBA -- variable in .formula

is there a more elegant (simpler) way to put a variable in .formula? I don't want to use .formulaR1C1
I have this code:
Range("C8").Select
Selection.End(xlDown).Select
PosR = ActiveCell.Row
KonR = PosR - 2
Range("N" & PosR).Select
aAddress = Range("$N$9").Address & ":" & Range("$N$" & KonR).Address
ActiveCell.Formula = "=SUM(" & aAddress & ")"
Obviously I want to put =SUM($N$9:$N$101) (101 is the last cell minus 2) into that cell and this code does the job. But I just want to be sure that this is the easiest way to do this.
The easiest way is to skip all that selecting and those variables
PosR = Range("C8").End(xlDown).Row
Range("N" & PosR).Formula = "=SUM($N$9:$N$" & PosR - 2 & ")"
Edit: to be more explicit, the easiest way is to use FormulaR1C1 but you said you didn't want to, so...
You can use the code below (without using Select and ActiveCell:
PosR = Range("C8").End(xlDown).Row
KonR = PosR - 2
Range("N" & PosR).Formula = "=SUM(" & Range("$N$9").Address & ":" & Range("$N$" & KonR).Address & ")"
Or, the much simplier version:
Range("N" & PosR).Formula = "=SUM($N$9:$N$" & KonR & ")"
Well you should be trying to avoid using Select in VBA. You've made the actual inclusion of a variable in the .Formula about a simple as it gets, but your whole code could be simplified:
PosR = Range("C8").End(xlDown).Row
Range("N" & PosR).Formula = "=SUM($N$9:$N$" & PosR - 2 & ")"
Really you should be fully qualifying your ranges too, like so
With ThisWorkbook.Sheets("Sheet1")
PosR = .Range("C8").End(xlDown).Row
.Range("N" & PosR).Formula = "=SUM($N$9:$N$" & PosR - 2 & ")"
End With
And if you have blank cells in column C then your use of xlDown will fail to find the last cell. You may want to look at ways of finding the last cell in VBA or simply use
' Again, preferably fully qualified
Range("C" & Rows.Count).End(xlUp).Row
Range("$N$9").Address gives exactly "$N$9".
Range("N9").Address gives the same. Thus, it is a bit overwork. Check out the first two debug.print in the sample below.
Thus, once you calculate the last row and assign value to it lngLast, it is possible to get the formula like this:
"=SUM(N9:N" & lngLast & ")"
Option Explicit
Public Sub TestMe()
Dim strA As String
Dim lngLast As Long
strA = Range("$N$9").Address
Debug.Print strA = "$N$9"
strA = Range("N9").Address
Debug.Print strA = "$N$9"
lngLast = Range("N" & Rows.Count).End(xlUp).Row - 2
ActiveCell.Formula = "=SUM(N9:N" & lngLast & ")"
End Sub
Good morning, everyone :)

Correct formula giving "Run-time error '1004': Application-defined or object-defined" error when running sub

I want to paste formula's in column B with a delay in between. The formula should only paste the formula if the cell left to it (in case of B1 this is A1) is not empty, like this:
I have the following VBA that pastes the formula with a delay of 1 sec.
Option Explicit
Sub RetrieveDataDelay()
'paste formulas into cells, then calculate, then delay rinse repeat
'=========================
'Declare Variables
'=========================
Dim i As Long 'used to loop
Dim rowCount As Long
Dim LastRow As Long 'used to find the last row
'=========================
'Setup for Speed
'=========================
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'=========================
'Define Variables
'=========================
LastRow = Worksheets(ActiveSheet.Name).Cells(Rows.Count, 1).End(xlUp).Row 'This will find the last used row in column A, change the number 1 to whatever column number you want
rowCount = 1 ' set to how many rows you want to do at a time
'=========================
'Do Work
'=========================
For i = 1 To LastRow Step rowCount
Range("B" & i, "B" & WorksheetFunction.Min(i + rowCount - 1, LastRow)).Formula = "'=IF(ISBLANK(A" & i & ");" & """" & """" & ";Dump(Volumes(A" & i & ";2528;1010;TRUE;" & "Volume" & ";TRUE)))" 'set the formula to whatever it needs to be
Calculate
Application.Wait (Now + TimeValue("00:00:01")) 'this delays 1 second
Next i
'=========================
'Setup for Speed - Reverse
'=========================
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
The error occurs at this part
Range("B" & i, "B" & WorksheetFunction.Min(i + rowCount - 1, LastRow)).Formula = "=IF(ISBLANK(A" & i & ");" & """" & """" & ";Dump(Volumes(A" & i & ";2528;1010;TRUE;" & "Volume" & ";TRUE)))"
The errors has something to due with the formula, which it does not accept. This is a custom formula used with an excel extension. I know that the formula works, as I put a single quotation mark in front as such:
Range("B" & i, "B" & WorksheetFunction.Min(i + rowCount - 1, LastRow)).Formula = "'=IF(ISBLANK(A" & i & ");" & """" & """" & ";Dump(Volumes(A" & i & ";2528;1010;TRUE;" & "Volume" & ";TRUE)))"
so that it pastes the formally literally. If I then remove the quotation mark from the formula the formula works. So the questions remains why it doesn't accept this specific formula in the VBA.
Using Excel 2013.
Range.Formula needs the formula notation always in en_us format independent of the current locale settings. That means functions in English language and also comma as delimiter between formula parameters and not semicolon.
So
.Formula = "=IF(ISBLANK(A" & i & ")," & """" & """" & ",Dump(Volumes(A" & i & ",2528,1010,TRUE," & "Volume" & ",TRUE)))"
After setting Range.Formula, the locale settings will be nevertheless active in the sheet. So in the sheet the formula will be delimited with semicolons if so set.
Btw.: The complicated string notation for double quotes is not neccessary.
.Formula = "=IF(ISBLANK(A" & i & "),"""",Dump(Volumes(A" & i & ",2528,1010,TRUE," & "Volume" & ",TRUE)))"

VBA search for corresponding line and compare values

I am new to VBA programming, and I am looking for a way to search a range of about 2,000 to 3,000 rows to compare quantities where ID numbers match, and generate a message box displaying the ID number if there are any matching ID numbers where quantities do not match. There are 2 matching ID numbers in the data.
I have found and adapted this code
`Dim rng1 As Range, rng2 As Range, rngName As Range, i As Integer, j As Integer
For i = 1 To Sheets("Sheet1 (2)").Range("q" & Rows.Count).End(xlUp).Row
Set rng1 = Sheets("Sheet1 (2)").Range("q" & i)
For j = 1 To Sheets("Sheet1 (2)").Range("q" & Rows.Count).End(xlUp).Row
Set rng2 = Sheets("Sheet1 (2)").Range("q" & j)
Set rngName = Sheets("Sheet1 (2)").Range("q" & j)
If rng1.Value = rng2.Value Then
If rng1.Offset(0, 2).Value <> rng2.Offset(0, 2).Value Then
MsgBox ("Not equal " & rng1 & " Net " & rng1.Offset(0, 2) - rng2.Offset(0, 2))
Exit For
End If
End If
Set rng2 = Nothing
Next j
Set rng1 = Nothing
Next i`
Honestly, this is beyond my current skill level in VBA, and I can't think of any way to use the Macro recorder to help. I want to know if there is any way to optimize this code to run faster, and also if there is a way to adapt it to write out all ID numbers with the amount of variance, instead of displaying the message box for each ID number individually.
Thanks!
If the data is sorted (assumes ID in column Q, quantity in Column R):
Dim ErrorList as String
With Sheets("Sheet1 (2)")
For i = 1 To .Range("q" & Rows.Count).End(xlUp).Row step 2
if .range("R" & i).value <> .range("R" & i+1) then
ErrorList = ErrorList & "ID: " & .range("Q" & I) & " Net: " & _
.range("R" & i).value - .range("R" & i+1).value & vbcrlf
end if
next
end with
'do something like MsgBox with ErrorList
If the data is NOT sorted (same column assumptions):
Dim ErrorList as String
With Sheets("Sheet1 (2)")
For i = 1 To .Range("q" & Rows.Count).End(xlUp).Row
'assume .range("q"
Set Rng = .Range("q:q").Find(what:=.range("q" & i), LookIn:=xlValues, _
lookat:=xlPart, MatchCase:=False)
If .range("Q" & I).value <> rng.cells(1,1).value then
ErrorList = ErrorList & "ID: " & .range("Q" & I) & " Net: " & _
.range("R" & i).value - .range("R" & i+1).value & vbcrlf
end if
next
end with
'do something like MsgBox with ErrorList
The .Find is MUCH quicker than an inner loop through all the rows of data again (someone a week or so ago tested and found something along the lines of 1000x times faster than a loop). Unfortunately, this method will leave you with duplicate IDs in your mismatch list, since it will run through the whole list, finding each of the pairs and discovering that they both don't match:
ID Value
ABC 1
BCD 6
ABC 2
It will loop to ABC/1, find ABC/2, then later in the loop find ABC/2 and discover that it doesn't match ABC/1, and report on both. The sorted data in the first option will work better if you can get your data sorted.
NOTE: No code was tested in the writing of this answer. There may be typos to resolve
You can do this with a formula if there can be at most only two matches: eg if ID is in ColA and Amount in ColB then in ColC enter
=IFERROR(VLOOKUP(A2,A3:B$9,2,FALSE)-B2,0)
and fill down. Result will be zero if no mismatch (or no matching Id), otherwise will be the difference between the two amounts.

Looping through cells, building a range in VBA

I am looking to loop through cells and build a range for a graph. My main issue is that I cannot figure out how to incorporate the 'i' into the range. Example:
Dim name As String
Dim newChart as Chart
Dim i as Integer
Set newChart = Charts.add
For i = 1 To 20
accName = Range("C" & i).Value 'I understand why this works.
With newChart
.ChartType = xlColumnClustered
.SeriesCollection.NewSeries
.SeriesCollection(1).Name = accName
.SeriesCollection(1).Values = wb.Worksheets("Summary-Account").Range("E&i:G&i, I&i:K&i, M&i:O&i, Q&i:S&i") 'How can I get this to work?
.SeriesCollection(1).XValues = wb.Worksheets("Summary-Account").Range("E3:G3, I3:K3, M3:O3, Q3:S3")
End With
i = i + 1
Loop
You don't increment manually i.
The function for loop already does it for you.
So remove that i = i + 1.
Now, to make your Range work, you would need its "" to be something like this : Range("E" & i & ":G" & i). I don't quite understand what you are trying to achieve with trying to take data from 6 different columns.. See range for further information.
You probably need to have:
.SeriesCollection(1).Values = wb.Worksheets("Summary-Account").Range("E" & i & ":G" & i & ", I" & i & ":K" & i & ", M" & i & ":O" & i & ", Q" & i & ":S" & i)
Not the clearest line ever, but should give you the pattern to go by. There are other problems like needing a "Next i" instead of a "Loop" and no i=i+1, but on my computer this gave me a graph with multiple series on it.
Try
.SeriesCollection(1).Values = Range("E1").Resize(20,1).Value
this will copy all the values into an array for use in series collection
use Next i instead of Loop; and get rid of that i = i+1.
Also, use "E" & i & ":G" & i instead of "E&i:G&i"
One step further, in vba
Dim i as double
For i = 1 to 100 Step 10 '<= Step 10 means when updating i, i = i + 10, and default value would be 1
Loop '<=breaks here, compile error is expected.
this is not even valid in syntax, the keyword Loop is associated with another keyword Do, and For is associated with Next