VBA Runtime error 1004 on Cells(..).Formula - vba

I can't make this simple command work:
Cells(l, 7).Formula = "=" & var1 & " * " & var2 & " * " & var3 & " / 252"
I can paste the inspected formula string value in Excel and it works as expected.
Cells(l,7) is a proper reference, as I can inspect its value.
Inspected formula on debug:
"=86710597,9409 * 0,02 * 0,35 / 252"

The problem is when a variable is represented as string it will have the system's decimal point. In your case it is a comma so you need to convert it to dot, for example using replace() function.

Related

Compile Error At IfError in VBA Code of Nested WorksheetFunctions

So, I'm quite new to VBA and I'm trying to learn. I have several tables with fastener data that I'm trying to pull information from based on what's in the main input table. I have a formula that works, but as I add different fastener tables, the nested IF formula is getting unruly. I decided to try to convert the formula to VBA and I'm getting an error: "Compile error: Wrong number of arguments or invalid property assignment." It shows up at the IfError. I may also have called the table columns incorrectly. The formula that I am trying to convert is included below. I haven't yet determined how best to set up the If statement so that if the user selected IFF, it would switch to using the IFF table, but that's another post.
Dim tbl_Solid As ListObject
Dim Rep_Fast_Type
Dim Incoming_Dia
Dim BP_Max_Dia
Dim Test_Dia
Dim Rep_Fast
Dim Test_Value
Dim i
Set tbl_Solid = ThisWorkbook.Sheets("Fastener DB").ListObjects("tbl_Solid")
i = 1
Incoming_Dia = [tbl_Input].Cells(i, 2)
BP_Max_Dia = [tbl_Input].Cells(i, 3)
Rep_Fast_Type = [tbl_Input].Cells(i, 4)
If Incoming_Dia > BP_Max_Dia Then
Test_Dia = Incoming_Dia
Else
Test_Dia = BP_Max_Dia
End If
'Compile error at IfError in third line.
If Rep_Fast_Type = "Solid" Then
Rep_Fast = WorksheetFunction.Index([tbl_Solid].Range("Fastener"), _
WorksheetFunction.Aggregate(15, 6, WorksheetFunction.IfError( _
Rows([tbl_Solid].Range("Fastener")) / ((Test_Dia >= [tbl_Solid].Range("min")) * (Test_Dia <= [tbl_Solid].Range("max"))), _
Rows([tbl_Solid].Range("Fastener")) / (Test_Dia <= [tbl_Solid].Range("min")), 1)))
End If
'To test values
MsgBox "Incoming diameter is " & Incoming_Dia & vbCrLf & "B/P max diameter is " & BP_Max_Dia & vbCrLf & "Test diameter is " & Test_Dia & vbCrLf & "Repair fastener type is " & Rep_Fast_Type & vbCrLf & "Repair Fastener is " & Rep_Fast
Old Excel Formula:
=IF([#[rep type]]="Solid",INDEX(tbl_Solid[[#All],[Fastener]],AGGREGATE(15,6,IFERROR(ROW(tbl_Solid[Fastener])/(([#diameter]>=tbl_Solid[min])*([#diameter]<=tbl_Solid[max])),ROW(tbl_Solid[Fastener])/([#diameter]<=tbl_Solid[min])),1)),IF([#[rep type]]="IFF",INDEX(tbl_IFF[[#All],[Fastener]],AGGREGATE(15,6,IFERROR(ROW(tbl_IFF[Fastener])/(([#diameter]>=tbl_IFF[min])*([#diameter]<=tbl_IFF[max])),ROW(tbl_IFF[Fastener])/([#diameter]<=tbl_IFF[min])),1))))
Screenshot of Data
It was just a parenthesis wrongly placed:
replace this line:
Rows([tbl_Solid].Range("Fastener")) / (Test_Dia <= [tbl_Solid].Range("min")), 1)))
with for this:
Rows([tbl_Solid].Range("Fastener")) / (Test_Dia <= [tbl_Solid].Range("min"))), 1))
Nevertheless, I would suggest to use the With statement to wrap the formula, i.e.:
With WorksheetFunction
Rep_Fast = .Index([tbl_Solid].Range("Fastener"), _
.Aggregate(15, 6, .IfError( _
Rows([tbl_Solid].Range("Fastener")) / _
((Test_Dia >= [tbl_Solid].Range("min")) * (Test_Dia <= [tbl_Solid].Range("max"))), _
Rows([tbl_Solid].Range("Fastener")) / (Test_Dia <= [tbl_Solid].Range("min"))), 1))
End With
Note that this answer refers only to the syntax that gives the compile error, no test have been performed to the formula output.

recordset.GetString in Access VBA Query returns an extra character after the result

I have a query that I execute through VBA in Access 2010. The result of the query should be AFR, but it returns AFR with an extra line below it. I have added the "'" character to make the extra line visible.
TempHold = rs.GetString
Debug.Print "'" & TempHold & "'"
Returns this:
'AFR
'
But should return this:
'AFR'
I have tried using the below code, but none of the If statements evaluate as True. The code should check for a " ", a vbNewLine, or vbCrLf character but none evaluate as true. Does anyone know of any additional characters that would result in a new line?
If Right(TempHold, 1) = " " Then
TempHold = Left(TempHold, Len(TempHold) - 1)
ElseIf Right(TempHold, 2) = vbNewLine Or Right(TempHold, 2) = vbCrLf Then
TempHold = Left(TempHold, Len(TempHold) - 2)
End If
Use:
Asc(Right(TempHold, 1))
to get the Ascii character code.
Once you've found the character code (which, as you wrote in your comment, was 13), you can use your code to remove it:
If Right(TempHold, 1) = Chr(13) Then
TempHold = Left(TempHold, Len(TempHold) - 1)
End If
In this case, you can also use vbCr, which is the same as Chr(13).
The best way to get rid of the carriage return in my opinion is to stop it being created in the first place. This method is a lot tidier than having to remove the last character.
In the .GetString method there is a parameter for RowDelimiter which by default is set to be a carriage return. However you can change this to be whatever you want including a zero length string as follows:
rs.GetString(, , , "")
If you run your debug again with this code:
rs.GetString(, , , "")
Debug.Print "'" & TempHold & "'"
You will get this result:
'AFR'
Remember if you want something different to be placed between rows then just change the zero length string to whatever you need.

Vba excel convert cell to Hebrew currency (ILS)

I am trying to convert cells with numbers to Hebrew currency format, instead of getting the sign of currency I get question mark sign like in an example attached.
I've rerecorded a macro but it just doesn't seem to work
Range("I4", "I" & LastRow).NumberFormat = _
"_ [$?-40D] * #,##0.00_ ;_ [$?-40D] * -#,##0.00_ ;_ [$?-40D] * ""-""??_ ;_ #_ "
Thank in advance, I would appreciate a lot If someone could answer my question
The VBA editor doesn't recognize the Hebrew currency symbol so you can use an ASCII character instead. The one your looking for is ChrW(8362). I found the correct character code from this website.
Example:
ActiveCell.NumberFormat = _
"_ [$" & ChrW(8362) & "-10D] * #,##0.00_ ;_ [$" & ChrW(8362) & "-10D] * -#,##0.00_ ;_ [$" & ChrW(8362) & "-10D] * ""-""tt_ ;_ #_ "
Result:

VBS script return expected result, how to compare float value?

I am getting an interesting result when executing the following VB script.
Set StdOut = WScript.StdOut
Set wbemSvc = GetObject("winmgmts://" & "." & "/root/cimv2")
Set biosSet = wbemSvc.ExecQuery("Select * from Win32_BIOS")
For Each biosObj In biosSet
StdOut.WriteLine "SMBIOSMajorVersion=" & biosObj.SMBIOSMajorVersion
StdOut.WriteLine "SMBIOSMinorVersion=" & biosObj.SMBIOSMinorVersion
Next
StdOut.WriteLine "Return value is: " & IsNewBiosVersion
Function IsNewBiosVersion()
On Error Resume Next
Set biosSet = wbemSvc.ExecQuery("Select * from Win32_BIOS")
newBios = 0
For Each bios In biosSet
minorFloat = "." & bios.SMBIOSMinorVersion
If bios.SMBIOSMajorVersion > 2 OR (bios.SMBIOSMajorVersion = 2 AND minorFloat >= .6) Then
newBios = 1
End If
Next
IsNewBiosVersion = newBios
End Function
The result is as follow. This looks contradictory since the SMBIOSMinorVersion=4, according to the code logic in the script, the return value should be 0!!!
SMBIOSMajorVersion=2
SMBIOSMinorVersion=4
Return value is: 1
I ran this same script on another system and got the expected correct result.
SMBIOSMajorVersion=2
SMBIOSMinorVersion=4
Return value is: 0
So what is the problem here?
New update:
We execute the following script again on the system, and found that the CDbl() function does not convert the string "2.4" to double value correctly, instead it converts it to 24! Looks like the dot "." was lost when converting, what is wrong with this? An bug in CDbl or a violation when use it?
here is the script
Set StdOut = WScript.StdOut
StdOut.WriteLine ""
StdOut.WriteLine "Simple Function to Test BIOS Version"
StdOut.WriteLine ""
Set wbemSvc = GetObject("winmgmts://" & "." & "/root/cimv2")
Set biosSet = wbemSvc.ExecQuery("Select * from Win32_BIOS")
For Each bios In biosSet
newBios = 0
StdOut.WriteLine "SMBIOSMajorVersion=" & bios.SMBIOSMajorVersion
StdOut.WriteLine "SMBIOSMinorVersion=" & bios.SMBIOSMinorVersion
temp = bios.SMBIOSMajorVersion & "." & bios.SMBIOSMinorVersion
StdOut.WriteLine "major dot minor=" & temp
currentBios = CDbl(bios.SMBIOSMajorVersion & "." & bios.SMBIOSMinorVersion)
StdOut.WriteLine ""
StdOut.WriteLine "currentBios=" & currentBios
If currentBios >= 2.6 Then newBios = 1
StdOut.WriteLine "return value is: " & newBios
Next
here is the output
Simple Function to Test BIOS Version
SMBIOSMajorVersion=2
SMBIOSMinorVersion=4
major dot minor=2.4
currentBios=24
return value is: 1
Remove your error handling - it s probably suppressing an issue.
On Error Resume Next ' Not a good idea
For one thing you are comparing a string to a double in these lines:
minorFloat = "." & bios.SMBIOSMinorVersion
If bios.SMBIOSMajorVersion > 2 OR (bios.SMBIOSMajorVersion = 2 AND minorFloat >= .6) Then
Why not just convert the major.minor values to floating-point for your test? You're currently doing two separate tests, with one being a string vs float comparison, which is unusual.
Maybe try this instead?
currentBios = CDbl(bios.SMBIOSMajorVersion & "." & bios.SMBIOSMinorVersion)
If currentBios >= 2.6 Then newBios = 1
You have to be careful comparing floating-point values when math operations are involved but for literal values you'll be fine.
And, as already mentioned, remove On Error Resume Next or you may never know why it works on one PC but not another.

Quadratic Complex roots solver

Cannot seem to make the console print out the complex roots correctly.
If quad4ac < 0 Then
Dim quad4acComplex As Long = quad4ac * -1
Dim quadiComplex As Long = -1
Dim quadrComplex As Long
Console.WriteLine(vbNewLine & "Your Roots Are Complexed!" & vbNewLine)
quadrComplex = (-quadCoB / (2 * quadCoA) & "+" & (quad4ac * -1) ^ 0.5 / (2 * quadCoA))
Console.WriteLine(quadrComplex)
Seems to be causing the console to crash.
You are trying to assign a string value to a long value and then print the long value. I don't really know what you are trying to do. In case you want to print out the calculated value try:
quadrComplex = CType((-quadCoB / (2 * quadCoA) + (quad4ac * -1) ^ 0.5 / (2 * quadCoA)), Long)
Console.Writeline(quadrComplex.Tostring)
In case you want to print out the expression try
Dim quadrComplex as String
quadrComplex = "(-" & quadCoB.Tostring & " / (2 * " & quadCoA.ToString & ") + (" & quad4ac.ToString & " * -1) ^ 0.5 / (2 * " & quadCoA.ToString & "))"
Console.Writeline(quadrComplex)
You should consider enabling Option Strict in your program. That way you are forced by the compiler to use the correct type conversions yourself. This avoids many many errors.
What are you trying to do with ampersands & here?
....(2 * quadCoA) & "+" & (quad4ac * -1)...
Problem is that & is a string concatenation in VB.NET, which of course cannot be assigned to a Long.
What do you expect console to print at this line?
Console.WriteLine(quadrComplex)
The answer for you will be somewhere between these two questions.