VBA How to add cell values without looping - vba

I have read about Application.WorksheetFunction.Sum but I was wondering if there is a specific method or property of the Range-object that does the job. I have looked into Range's members but I didn't find anything.
Is there a way to add without the use of a worksheet function? And without having to loop through each cell. Something like:
Sub test()
Range("A1") = 1
Range("A2") = 0
Range("A3") = 2
Range("A4") = Range("A1:A3").Add
MsgBox Range("A4")
End Sub
With output 3.

go on then, a 4th way :o)
evaluate(join(application.transpose(range("a1:a5").Value),"+"))

In general, there is a third way, which you did not mention:
Application.Sum
It is a bit different than WorksheetFunction.Sum, in the fact that it is a bit more discrete - it does not throw errors with a MsgBox, even when it should.
Something like this will have only 2 errors thrown with MsgBox and you will get 2 errors in the immediate window:
Option Explicit
Public Sub WaysOfSumming()
'This is Div/0 Error:
Range("A1").Formula = "=5/0"
Debug.Print Excel.WorksheetFunction.Sum(Range("A1"), 3, 5)
Debug.Print Application.Sum(Range("A1"), 3, 5)
Debug.Print Excel.WorksheetFunction.Sum(Range("A1"), 3, 5)
Debug.Print Application.Sum(Range("A1"), 3, 5)
End Sub

Related

VBA Vlookup using ActiveCell as reference [duplicate]

This question already has answers here:
How to error handle 1004 Error with WorksheetFunction.VLookup?
(3 answers)
Closed 4 years ago.
I am trying to develop a form to track invoices as they come in. The form will have a combobox where I can click on and select a vendor number. I want the textbox to automatically fill in based on the vendor number selected from the combobox. Here's what I have so far:
Private Sub ComboBox1_Change()
'Vlookup when ComboBox1 is filled
Me.TextBox1.Value = Application.WorksheetFunction.VLookup( _
Me.ComboBox1.Value, Worksheets("Sheet3").Range("Names"), 2, False)
End Sub
Worksheet 3 is from which the information is being drawn (the vendor number and name).
When I go back to the form to test the code, I get the following error:
Run-time error '1004': Unable to get the VLookup property of the WorksheetFunction class
How do I fix this?
Try below code
I will recommend to use error handler while using vlookup because error might occur when the lookup_value is not found.
Private Sub ComboBox1_Change()
On Error Resume Next
Ret = Application.WorksheetFunction.VLookup(Me.ComboBox1.Value, Worksheets("Sheet3").Range("Names"), 2, False)
On Error GoTo 0
If Ret <> "" Then MsgBox Ret
End Sub
OR
On Error Resume Next
Result = Application.VLookup(Me.ComboBox1.Value, Worksheets("Sheet3").Range("Names"), 2, False)
If Result = "Error 2042" Then
'nothing found
ElseIf cell <> Result Then
MsgBox cell.Value
End If
On Error GoTo 0
I was having the same problem. It seems that passing Me.ComboBox1.Value as an argument for the Vlookup function is causing the issue. What I did was assign this value to a double and then put it into the Vlookup function.
Dim x As Double
x = Me.ComboBox1.Value
Me.TextBox1.Value = Application.WorksheetFunction.VLookup(x, Worksheets("Sheet3").Range("Names"), 2, False)
Or, for a shorter method, you can just convert the type within the Vlookup function using Cdbl(<Value>).
So it would end up being
Me.TextBox1.Value = Application.WorksheetFunction.VLookup(Cdbl(Me.ComboBox1.Value), Worksheets("Sheet3").Range("Names"), 2, False)
Strange as it may sound, it works for me.
Hope this helps.
I was just having this issue with my own program. I turned out that the value I was searching for was not in my reference table. I fixed my reference table, and then the error went away.

Do nothing in vba

Is there an equivalent to python "pass" in VBA to simply do nothing in the code?
for example:
For Each ws In ThisWorkbook.Sheets
If ws.Name = "Navy Reqs" Then
ws.Select
nReqs = get_num_rows
Cells(1, 1).Select
If ActiveSheet.AutoFilterMode Then Cells.AutoFilter
Selection.AutoFilter
ElseIf ws.Name = "temp" Then
pass
Else
ws.Select
nShips = get_num_rows
End If
Next
I get an error here that pass is not defined. Thanks.
just remove pass and re run the code. VBA will be happy to accept that I believe
Don't include any statements:
Sub qwerty()
If 1 = 3 Then
Else
MsgBox "1 does not equal 3"
End If
End Sub
Just leave it blank. You can also use a Select statement, it's easier to read.
For Each ws In ThisWorkbook.Sheets
Select Case ws.Name
Case "Navy Reqs":
'...
Case "temp":
'do nothing
Case Else:
'...
End Select
Next
Write code that does what it says, and says what it does.
For Each ws In ThisWorkbook.Sheets
If ws.Name = "Navy Reqs" Then
ws.Select
nReqs = get_num_rows
Cells(1, 1).Select
If ActiveSheet.AutoFilterMode Then Cells.AutoFilter
Selection.AutoFilter
Else If ws.Name <> "temp" Then
ws.Select
nShips = get_num_rows
End If
Next
That's all you need. An instruction that means "here's some useless code" does not exist in VBA.
You want comments that say why, not what - a comment that says 'do nothing is the exact opposite of that. Don't write no-op code, it's pure noise.
Assuming Python's pass works like C#'s continue statement and skips to the next iteration, then the VBA equivalent is the one and only legitimate use of a GoTo jump:
For ...
If ... Then GoTo Skip
...
Skip:
Next
This code shows an IF test that keeps searching unless it gets a match.
Function EXCAT(Desc)
Dim txt() As String
' Split the string at the space characters.
txt() = Split(Desc)
For i = 0 To UBound(txt)
EXCAT = Application.VLookup(txt(i), Worksheets("Sheet1").Range("Dept"), 2, False)
If IsError(EXCAT) Then Else Exit Function
Next
' watch this space for composite word seach
EXCAT = "- - tba - -"
End Function
I coded in COBOL for many years and the equivalent 'do nothing' statement is NEXT SENTENCE.
In VBA, I find myself creating a dummy variable (sometimes a global) dim dummy as integer and then when I need that 'do nothing' action in an If..Then..Else I put in a line of code: dummy = 0.
This is actually a legit question. I want to run a debug routine that stops when a certain critical value is, say, 8, i.e., set break point at x = 8 and then step through line by line. So the following construct is useful:
Select Case x
Case 21
'do nothing
Case 8
'do nothing
Case 14
'do nothing
Case 9
'do nothing
End Select
Since you can't put a break point on a comment, an actual statement is needed.
You also can't put a break point on the Case statements because that gets executed every time.
Obviously anything here is OK e.g., x=x, but it would be nice to have something formal like pass.
But I've been using x=x.
Most languages have a "null" or "empty" statement like Python's pass. These statements have evolved because they are practically useful, and in some grammars, necessary. For example, as others have suggested, null statements can serve as side-effect free anchors for a debugger.
I use:
Debug.Assert True
Note that if your use case is to set a conditional breakpoint, you may find Stop more useful, as in:
If targetShape.Type = msoAutoShape Then
Stop
End

VBA 2042 Type mismatch - #N/A - Array

I would have a problem in creating an array, which contains a number of data, which then will be merged into one file. During reading the info from the files, then having them put into the another merged file, the loop in which it is situated it find a 2042 error. I found in Add Watch that it wants to give back #N/A as the function in the original file does not returns anything. How can I avoid my macro stopping? I have found ways to skip this record, but I cannot insert it into my current loop because of insufficient experience in handling these. It stops at here "If aOutput(1, outputCol) = aDataFromPivotFiltered(1, filteredCol) Then" See below a small bit of the macro.
For outputCol = 1 To UBound(aOutput, 2)
For filteredCol = 1 To UBound(aDataFromPivotFiltered, 2)
If aOutput(1, outputCol) = aDataFromPivotFiltered(1, filteredCol) Then
For filteredRow = 2 To UBound(aDataFromPivotFiltered, 1)
aOutput(filteredRow, outputCol) = aDataFromPivotFiltered(filteredRow, filteredCol)
Next filteredRow
Exit For
End If
Next filteredCol
Next outputCol
I have found the below, which would be ok, but it is applied another macro.
Sub Test()
Dim varIn As Variant
[a1].FormulaR1C1 = "=NA()"
If IsError([a1].Value2) Then
varIn = "skip record"
Else
varIn = [a1].Value2
End If
End Sub
Is there anyone who could help me with this? It keeps causing headaches not matter how many article I am reading in this topic. Cannot figure out.
Test for errors first, like below:
If Not IsError(aDataFromPivotFiltered(1, filteredCol) And Not IsError(aOutput(1, outputCol)) Then
If aOutput(1, outputCol) = aDataFromPivotFiltered(1, filteredCol) Then
For filteredRow = 2 To UBound(aDataFromPivotFiltered, 1)
aOutput(filteredRow, outputCol) = aDataFromPivotFiltered(filteredRow, filteredCol)
Next filteredRow
Exit For
End If
End If
This way, any formula errors that are passed into the array will be skipped.

Application Defined error on Simple range

I am trying to debug this code for quite some time already does anyone know what is the problem in it?
Code:
Sub Find_Field_List()
Dim Last_Field As Integer
Dim Field_List() As Variant
Last_Field = Summary_File.Sheets("Settings").Cells(1, 1).End(xlDown).Row
Field_List() = Summary_File.Sheets("Settings").Range(Cells(2, 1), Cells(Last_Field, 1))
End Sub
Error(highlights line starting with Field_List()):
RunTime Error 1004
Application-Defined or Object-Defined Error
Immediate Window:
?Summary_file.Sheets(2).Name
Settings
Split MBSA.xlsm
?Range(Cells(2,1),Cells(5,1)).Count
4
?Last_Field
5
?Summary_File.Sheets(2).Range(Cells(1,1))
Fields
The reason is very simple in my opinion. The error with your code is that the cells Cells(2, 1) and Cells(Last_Field, 1) are not fully qualified. And you are getting this error because Summary_File.Sheets("Settings") is not active when the code is running. And hence one should always fully qualify the objects.
Try this. Notice the DOT before them in the code below.
Sub Find_Field_List()
Dim Last_Field As Integer
Dim Field_List() As Variant
With Summary_File.Sheets("Settings")
Last_Field = .Cells(1, 1).End(xlDown).Row
Field_List = .Range(.Cells(2, 1), .Cells(Last_Field, 1)).Value
End With
End Sub
EDIT:
One more tip: Try and avoid the use of .End(xlDown).Row You may end up selecting the entire column! If you want to select only till the last row then you may want to see THIS

How do I specify a range in the do until loop in VBA?

I'm writing a code, so that
Do Until Range("A1:A10")=5
""
Loop
I want a certain range to all have the same numbers, but VBA keeps on telling me there's a type mismatch. It seems that you can only work with one cell at a time or you would have to use the "And" function? (Do Until Range("A1")=5 And Range("A2")=5 , etc.) But is there a way to have the loop run until a certain range of cells satisfies the condition?
I think you're looking for something like this:
Dim rngUpdate As Range
Set rngUpdate = Range("A1:A5")
Do Until WorksheetFunction.CountIf(rngUpdate, 5) = rngUpdate.Cells.Count
'Your code goes here
Loop
You can also use "for next", in your case:
For i = 1 To 10
If Cells(i, 1) = "5" Then
Exit For ' when cell value is 5, it exits loop
Else
*do other code*
End if
Next i