I have an issue. I have values in a workbook that are getting read into an array. The values come from an XML list so sometimes can be numbers or text, and if they are numbers in text format ("1" for example), they need to be converted to number format, so I multiply them by 1. If the value is text "LS" for example, I am trying to use an error handler to keep the value as "LS".
I have developed the code below: It works once, but the next time I use a similar method (with 'Dummy2') the code it produces a 'Type Mismatch' error.
On Error GoTo Dummy1
For i = 1 To nrows1 - 1
If (Worksheets("Import").Cells(i + 1, 26) * 1 = "") Then
Dummy1:
Table1(i, 1) = Worksheets("Import").Cells(i + 1, 26)
Else
Table1(i, 1) = Worksheets("Import").Cells(i + 1, 26) * 1
End If
Next
On Error GoTo 0
I also tried Clearing Err after the above code with no success.
Please help!
You can use the IsNumeric function:
Sub test3()
Dim Test As Variant
Dim i As Long
For i = 1 To nrows1 - 1
Test = Worksheets("Import").Cells(i + 1, 26)
If IsNumeric(Test) Then
Table1(i, 1) = Test * 1
Else
Table1(i, 1) = Test
End If
Next
End Sub
use VAL(Worksheets("Import").Cells(i + 1, 26)) to determine if it is a Number or not. VAL will give you 0 for "LS".
You could try TryParse functions - but not sure if its available in your version of VBA
Related
I am wishing to replace an include file with ~ 25 declared Constants by dynamically creating those constants from a Recordset (or Array). I have tried looping through a record set and have also tried populating a 2D array and then trying to set these Constants from the array values but it seems to take what is after the "Const" literal and not the value.
If (not rsVars.Eof) Then
cCount = rsVars.RecordCount
ReDim cArray(cCount - 1, 1)
For i = 0 To cCount - 1
cArray(i, 0) = rsVars("VariableNm")
cArray(i, 1) = rsVars("Value")
rsVars.MoveNext
Next
End If
For i = 0 To cCount - 1
' Display the Array Elements - WORKS and Displays All Variables and Desired Values
Response.write "("&(i+1)&") " & cArray(i, 0) & " = " & cArray(i, 1) & "<br>"
' Attempt to set Constant Variables - this next line errors - "Name_redefined"
Const cArray(i, 0) = cArray(i, 1)
Next
You could use the server.execute method to achieve this.
But it needs a FILE path to do so.
You will need to create a file dynamically using the FileSystemObject and pass the file's full path to the server.execute method to make those variables available as constants.
ex:
constants.asp
Note
Values will be CONSTANT Across user sessions and requests.
If you need a different set of constants by user, company, date etc, you will need to change the filename to include the unique constants-.asp and execute that file.
References
https://www.w3schools.com/asp/met_execute.asp
https://www.w3schools.com/ASP/asp_ref_filesystem.asp
I am trying to implement a calculator using VBA. I am facing trouble with calculating the result using recursion.
I've tried implementing the function. I always end up getting the result to be zero.
Idea:
For example, 2+3+4+5 is to be calculated
The function will recursively read and combine two elements with every step. For instance, at step 2, from the first position, the first two slots of the array give you "2" and "+" so you know that you need to add 2 to the rest of the array starting from position 3. Finally, the result of the array would be 5 (from step 5) + 4 (from step 4) + 3 (from step 3) + 2 (from step 2) = 14.
Please find the code below. I have tried implementing it but I am getting type mismatch error. "Display" is a string to remember the current display of the calculator.
Dim Memory(1 To 100) As String
' The current position used by the calculator inside the memory array
Dim CurrentPos As Integer
' This function is a recursive function for calculating the result of the expression
' stored in the Memory array, starting at the position Pos.
'
' Note that the return value is a Long number. When you calculate the result you need
' to convert the numbers (as text) in the memory to long numbers using CLng().
Function CalcTotal(ByVal Pos As Integer) As Long
'
' Task 4: Calculating the Result Using Recursion
'
' Case 1: if Pos is bigger than what you have in the Memory array
' Nothing is available
' Case 2: if Pos is exactly at the end of the Memory array
' Return the number in the position
' Case 3: Memory(Pos) is a number and Memory(Pos + 1) is an operator
' Return the number in the current position together with the rest of the Memory array
If Pos > CurrentPos Then ' Case 1: Nothing left to read
Display = "0"
'return 0 as the result because there is nothing to do...
ElseIf Pos = CurrentPos Then ' Case 2: There is only a number left
Display = CLng(Memory(Pos))
'return the number in the current position...
Else ' Case 3: Read the next two slots of the array and combine with the rest of the array
Display = CLng(Memory(Pos)) + CLng(Memory(Pos + 1))
CalcTotal (Pos + 2)
End If
End Function
This might help you get started:
Public MyInputs As Variant
Sub Test()
MyInputs = Array("2", "+", "3", "+", "4", "+", "5")
Debug.Print Application.Evaluate(CalcTotal(UBound(MyInputs))) '~~> prints 14
End Sub
Function CalcTotal(n As Integer) As String
If n = 0 Then
CalcTotal = MyInputs(n)
Else
CalcTotal = MyInputs(n) & (CalcTotal(n - 1))
End If
End Function
Notes:
CalcTotal will return a string e.g. 5+4+3+2
Application.Evaluate parses that string as a computation and prints 14
The problem in the code is , You are returning a String "0" , for a function who returns LONG , the correction is replace the "0" (string) to a 0 (long).
' This function is a recursive function for calculating the result of the expression
' stored in the Memory array, starting at the position Pos.
'
' Note that the return value is a Long number. When you calculate the result you need
' to convert the numbers (as text) in the memory to long numbers using CLng().
Function CalcTotal(ByVal Pos As Integer) As Long
'
' Task 4: Calculating the Result Using Recursion
'
' Case 1: if Pos is bigger than what you have in the Memory array
' Nothing is available
' Case 2: if Pos is exactly at the end of the Memory array
' Return the number in the position
' Case 3: Memory(Pos) is a number and Memory(Pos + 1) is an operator
' Return the number in the current position together with the rest of the Memory array
If Pos > CurrentPos Then ' Case 1: Nothing left to read
' Display = "0" WRONG THATS A STRING
Display = 0
'return 0 as the result because there is nothing to do...
ElseIf Pos = CurrentPos Then ' Case 2: There is only a number left
Display = CLng(Memory(Pos))
'return the number in the current position...
Else ' Case 3: Read the next two slots of the array and combine with the rest of the array
Display = CLng(Memory(Pos)) + CLng(Memory(Pos + 1))
CalcTotal (Pos + 2)
End If
End Function
I have a long array that exceeds the maximum number of rows of a single column (1048576), and I wish to output this array into multiple columns, for example, if my array length is 3145728, and so I intend to create 3 separate arrays, each with length 1048576, so 1 to 1048576 would be output to column A, 1048577 to 2097152 to column B, and 2097153 to 3145728 to column C. My code attempted is as follows:
Sub test()
'for simplicity, just created a simply long array
Dim arrIn(1 To 3145728, 1 To 1) As Long
For i = 1 To 3145728
arrIn(i, 1) = i
Next i
'created 3 separate arrays, each with length of 1048576
Dim arrOut1(1 To 1048576, 1 To 1) As Long, arrOut2(1 To 1048576, 1 To 1) As Long, arrOut3(1 To 1048576, 1 To 1) As Long
Dim p As Long, p2 As Long, p3 As Long
'because counter p is going to be from 1 to 3145728, for the second and third arrays, the counter need to restart from 1 and upto 1048576
p2 = 1
p3 = 1
For p = 1 To 3145728
Select Case p
Case Is <= 1048576
arrOut1(p, 1) = arrIn(p, 1)
Case Is <= 2097152
arrOut2(p2, 1) = arrIn(p, 1)
p2 = p2 + 1
Case Is <= 3145728
arrOut3(p3, 1) = arrIn(p, 1)
p3 = p3 + 1
End Select
Next p
Range("A1:A1048576") = arrOut1
Range("B1048577: B2097152") = arrOut2
Range("C2097153:C3145728") = arrOut3
End Sub
The first column (arrOut1) was output to column A, however, when it comes to the second column (arrOut2), VBA returns Run-time error '1004': Menthod 'Range' of object '_Global' failed.
I checked the locals windows results, p2 and p3 were 1048577, and arrOut2(1,1) = 1048577, arrOut2(1,1) = 1048578, and so on, seems the arrays all get populated, however I'm not sure what is prohibiting them from being spitted out to the columns. Thank you for your advice.
Ok so, just realized that Range(“B1048577:B...) was nonsense... so it is solved. Thank you!
I suspect my question has a very simple answer, and yet I cannot find an answer that I understand in searching all over the site.
Ticker1 = an array of stock prices (1 to 2542)
PctChg1 = an array which I hope will ultimately hold the results of
(Price_last / Price_prev) - 1
i = counter
Code:
For i = 2 To UBound(Ticker1)
PctChg1(i, 1) = Ticker1(i, 1) / Ticker1(i - 1, 1) - 1
Next i
Something about the Ticker1(i - 1, 1) part it does not like - I have fooled around with ranges as well and cannot make sense of this. I don't know why it thinks I am dividing by a number that isn't there - if i am starting at point 2 of the array, why wouldn't I be able to reference point 1 ?
For i = 2 To UBound(Ticker1)
If Val(Ticker1(i - 1, 1)) <> 0 Then PctChg1(i, 1) = Ticker1(i, 1) / Ticker1(i - 1, 1) - 1
Next i
This works, but I still have not established why i-1 generates errors when I start the calculation on data point i=2.
The following code doesn't remove the rows that are duplicates - Type Mismatch Error. I have the complication that I dont know how many columns there is. Please could someone tell me what I have done wrong. Thank you
ReDim myarray(endcol - 2)
For echarrayval = 1 To endcol - 1
myarray(echarrayval - 1) = eacharracycol
Next echarrayval
remduprng = Range(Cells(1, 1), Cells(botrw, endcol - 1)).Address
ActiveSheet.Range(remduprng).RemoveDuplicates Columns:=Array(myarray), Header:=xlYes