I'm trying to write vba code so that every time I type a number, it becomes a stock ticker after "HK Equity" is added by vba code. Then spreadsheet can return its RSI using Bloomberg function BTP. For example, when I type "1" in a cell, spreadsheet will return the RSI of stock "1 HK Equity" using Bloomberg function =BTP($D3,E$2,"RSI","TAPeriod=14","DSClose=LAST_PRICE","Per=d").
Here are my code:
Sub RSI()
Dim num As Integer
num = Sheets("sheet2").Cells(3, 2).Value
Dim numString As String
numString = CStr(num)
Dim ticker As String
ticker = numString + "HK Equity"
Dim rsiString As String
rsiString = Sheets("sheet2").Cells(4, 2).Value
Sheets("sheet2").Cells(5, 2).Value = "=BTP(" & ticker & "," & rsiString & "," & "RSI" & ", " & "TAPeriod=14" & "," & "DSClose=LAST_PRICE" & "," & "Per=d" & ")"
End Sub
When I run the code it says Run-time Error '1004': application-defined or object-defined error. And debugger says the last command has a problem (i.e. Sheets("sheet2").Cells(5, 2).Value = "=BTP....) What's wrong with this command? THX!!
May you check the output of BTP formula?
' =BTP(1 HK Equity,rsi string,RSI, TAPeriod=14,DSClose=LAST_PRICE,Per=d)
Sheets("sheet2").Cells(5, 2).Value = "=BTP(" & ticker & "," & rsiString & "," & "RSI" & ", " & "TAPeriod=14" & "," & "DSClose=LAST_PRICE" & "," & "Per=d" & ")"
seems you have miss all escape character
"=BTP(""" & ticker & """,""" & rsiString & """,""RSI"",""TAPeriod=14"",""DSClose=LAST_PRICE"",""Per=d"")"
Related
I'm trying to select differrents worksheets, based on a variable.
All this in a purpose to print those sheets into a pdf.
I've tried with arrays but i don't know much.
So I'm continuing with string and split.
But I have no chance too.
All is ok except the last codeline , the sheets selection.
I receive a Subscript OutOf range
Any advice?
Sub Print_Full_Report()
Call Clear_clipboard
Call Stop_Calcul_Screen
LastOverviewRow = WS_Rep_Overview.Cells(Rows.Count, 3).End(xlUp).Row
tabtoprint = ""
SelectedDate = Date + 90
For i = 5 To LastOverviewRow
If WS_Rep_Overview.Range("E" & i) < SelectedDate Then
Module = WS_Rep_Overview.Range("D" & i).Value
tabtoprint = tabtoprint & Chr(34) & Module & Chr(34) & "," & Chr(34) & Module & "-Cow" & Chr(34) & "," & Chr(34) & Module & "-SubSys" & Chr(34) & ","
End If
Next i
tabtoprint = Mid(tabtoprint, 1, Len(tabtoprint) - 1)
Sheets(Split(tabtoprint, ",")).Select
End Sub
Try this code:
Sub Print_Full_Report()
Const template = ",#,#-Cow,#-SubSys" ' for further use in the loop
' previous your code ...
' in the code some redundant variables have been removed
With WS_Rep_Overview
SelectedDate = Date + 90
For i = 5 To .Cells(Rows.Count, 3).End(xlUp).Row
If .Range("E" & i) < SelectedDate Then
tabtoprint = tabtoprint & Replace(template, "#", .Range("D" & i).Value)
End If
Next i
End With
tabtoprint = Mid(tabtoprint, 2) 'remove the leading comma
' for debug; check that it prints something like this: Module5,Module5-Cow,Module5-SubSys,Module6,Module6-Cow,Module6-SubSys,Module7,Module7-Cow,Module7-SubSys
Debug.Print tabtoprint
Worksheets(Split(tabtoprint, ",")).Select
End Sub
I am wrestling with the syntax of this one line of some code. the formula with "IfError" seems to have the wrong syntax. I believe I have the quotes in the right places.
Dim j As Integer
Dim MidPointE As String
Dim Dist As String
Dim Allocation As String
MidPointE = "AM"
Dist = "AN"
Allocation = "AO"
for J= 1 to 300
Cells(j, Dist).Formula = "=IFERROR(" & MidPointE & j & " / " & MidPointE & CustomerLast & ", "")"
Cells(j, Allocation).Formula = "=" & Allocation & j & "* S" & CustomerLast
Next J
You can also assign multiple formulas at the same time:
Range("AN1:AN300").Formula = "=IFERROR(AM1 / AM$" & CustomerLast & ", """")"
Range("AO1:AO300").Formula = "=AO1 * S$" & CustomerLast
I also recommend looking into Excel Tables and Structured References
To avoid the circular reference issue, you can calculate the formulas and assign the values directly:
Range("AN1:AN300") = Evaluate("IFERROR(AM1:AM300 / AM$" & CustomerLast & ", """")")
Range("AO1:AO300") = Evaluate("INDEX(AO1:AO300 * S$" & CustomerLast & ",)")
Try this:
Cells(j, Dist).Formula = "=IFERROR(" & MidPointE & j & " / " & MidPointE & CustomerLast & ", """")"
Quotes inside a string literal must be escaped - and that's done by doubling them up.
It's at the end here
& ", "")"
The two quotes between the comma and ) end the string and start a new one.
'first string
","
'second string
")"
Since you can't just throw two strings together like that, i would replace the two quotes with the CHR equivalent. Should look something like this:
Cells(j, Dist).Formula = "=IFERROR(" & MidPointE & j & " / " & MidPointE & CustomerLast & ", "& CHR(034) & CHR(034) & ")"
'pretty sure 034 is the ascii code for "
I have a for statement in a VBA script that goes through each cell in a range (number of cells in range is variable based on user input - could be three cells could be 100). Each instance of the for loop calls an input box. How do I assign the user input from each instance of the for loop to a variable for later use?
Here is the for with the input box:
For Each cell In MyQCData
text_string = cell.Value
WrdArray() = split(text_string, ",")
For i = LBound(WrdArray) To UBound(WrdArray)
strg = strg & vbNewLine & "Part No. " & i & " - " & WrdArray(i)
Next i
InputBox ("This part requires a " & WrdArray(0) & " measurement of the " & _
WrdArray(1) & vbNewLine & vbNewLine _
& "The range for this is input is " & vbNewLine & vbNewLine & "Lower Control Limit " _
& WrdArray(2) & vbNewLine & "Upper Control Limit " & WrdArray(3))
Erase WrdArray()
Next cell
Yes, use an array:
Dim inputBoxAnswers() As String
ReDim inputBoxAnswers(1 To MyQCData.Cells.Count)
Dim cellCounter As Long
For Each cell In MyQCData
text_string = cell.Value
WrdArray() = split(text_string, ",")
'Is this loop needed???
For i = LBound(WrdArray) To UBound(WrdArray)
strg = strg & vbNewLine & "Part No. " & i & " - " & WrdArray(i)
Next i
cellCounter = cellCounter + 1
inputBoxAnswers(cellCounter) = InputBox("This part requires a " & _
WrdArray(0) & " measurement of the " & _
WrdArray(1) & _
vbNewLine & vbNewLine & _
"The range for this is input is " & _
vbNewLine & vbNewLine & _
"Lower Control Limit " & WrdArray(2) & _
vbNewLine & _
"Upper Control Limit " & WrdArray(3))
Next cell
If your MyQCData range is not a single column or a single row, you may find it easier to use a two-dimensional array, which could (perhaps) be dimensioned using
Dim inputBoxAnswers() As String
ReDim inputBoxAnswers(1 To MyQCData.Rows.Count, 1 To MyQCData.Columns.Count)
but then you will need to rework the indexes to use when assigning the elements their values. It would probably need to be
inputBoxAnswers(cell.Row - MyQCData.Row + 1, cell.Column - MyQCData.Column + 1) = ....
but a lot depends on how you intend to use the array afterwards.
It's kind of hard to tell without the rest of your code, but I assume that MyQCData is a Range. Try the below. I sort of "brute forced" the Inputbox look with k, FYI.
Dim k As Long
k = 0
Dim inputArr() As Variant
ReDim inputArr(myqcdData.Cells.Count)
For Each cell In MyQCData
text_string = cell.Value
WrdArray() = Split(text_string, ",")
For i = LBound(WrdArray) To UBound(WrdArray)
strg = strg & vbNewLine & "Part No. " & i & " - " & WrdArray(i)
Next i
inputArr(k) = InputBox("This part requires a " & WrdArray(0) & " measurement of the " & _
WrdArray(1) & vbNewLine & vbNewLine _
& "The range for this is input is " & vbNewLine & vbNewLine & "Lower Control Limit " _
& WrdArray(2) & vbNewLine & "Upper Control Limit " & WrdArray(3))
k = k + 1
Erase WrdArray()
Next cell
'Check each value in the array. This is optional and can be removed/commented out
For k = LBound(inputArr) To UBound(inputArr)
Debug.Print inputArr(k)
Next k
Edited per #Yow's astute comment
I'm going to dress this in a standalone code that you can easily run to get a feel for what's going on. Array variables must be declared hence Dim userInput(99) and the 99 is the upper limit (0-99 = 100 possible values). The first line of the first loop sets the variables, that's userInput(j) = InputBox("Sample InputBox", "InputBox Title", "blah" & j) the "blah" & j bit is the default entry, which is useful when you're writing/debugging as it's a lot faster to keep entering dummy data...
Sub inputBoxEg()
Dim userInput(99)
Dim MyQCData As Range
Set MyQCData = Range("A1:A4")
'Set InputBox inputs to a variable array called userInput:
j = 0
For Each cell In MyQCData
userInput(j) = InputBox("Sample InputBox", "InputBox Title", "blah" & j)
If userInput(j) = "" Then Exit Sub 'if user pressed cancel or entered blank
j = j + 1
Next cell
'Collate variables collected by InputBoxes in a text string called allInputs:
allInputs = ""
For i = 0 To j - 1
If i = 0 Then
allInputs = i & ": " & userInput(i)
Else
allInputs = allInputs & vbNewLine & i & ": " & userInput(i)
End If
Next i
MsgBox allInputs
End Sub
I am getting a this error:
Compile error: Expected: End of Statement
While trying to use an Excel formula in a VBA statement in the code below.
The error occurs on "FIND("for ","...
For i = 2 To lastRow
aa = ThisWorkbook.Sheets(3).Cells(i, "A").Text
ThisWorkbook.Sheets(3).Cells(i, "E").Formula = "=MID(aa,FIND("for ",aa)+4,FIND(" ",aa,FIND("for ",aa)+4)-(FIND("for ",aa)+4))"
Next i
It's a little long:
You need to add the " inside your formula, I like to use the Chr(34) to add it.
So first, your aa is a varaible that changes every time you advance i in the loop, so inside the formula you need to break the constant part and add " & aa & " every time you use it.
But, you need to add the " to aa, that's why I modifed your aa line to:
aa = Chr(34) & ThisWorkbook.Sheets(3).Cells(i, "A").Text & Chr(34)
Second, I added a String variable named Myfor, and set the value to it Myfor = Chr(34) & "for " & Chr(34), just to try to "shorten" the formula a little.
Code
Dim aa As String
Dim Myfor As String
Myfor = Chr(34) & "for " & Chr(34)
For i = 2 To lastRow
aa = Chr(34) & ThisWorkbook.Sheets(3).Cells(i, "A").Text & Chr(34)
ThisWorkbook.Sheets(3).Cells(i, "E").Formula = "=MID(" & aa & ",FIND(" & Myfor & "," & aa & ")+4, FIND("" ""," & aa & ",FIND(" & Myfor & "," & aa & ")+4)-(FIND(" & Myfor & "," & aa & ")+4))"
Next i
I have a piece of code that loops down a column and inserts a formula into each cell in that column. The code runs, the only problems is that each cell the formula is inserted into displays #Value! Does anyone know how to fix this?
Here is the piece of code with the problem:
Dim j As Long
'Loop down the rows in mainfile
For j = 2 To lastFullRow2
' Make each argument a string, then concatenate it all all into large string
Dim firstArgument As String
firstArgument = "ws_multidax.Range(" & valuecolumnLetter & "2:" & valuecolumnLetter & lastFullRow1 & ")"
Dim secondArgument As String
secondArgument = "ws_multidax.Range(" & parameter1columnLetter & "2:" & parameter1columnLetter & lastFullRow1 & ")"
Dim thirdArgument As String
thirdArgument = "ws_multidax.Range(" & parameter2columnLetter & "2:" & parameter2columnLetter & lastFullRow1 & ")"
Dim fourthArgument As String
fourthArgument = "ws_multidax.Range(" & parameter2columnLetter & "2:" & parameter2columnLetter & lastFullRow1 & ")"
Dim condition3 As String
condition3 = "ws_mainfile.Range(" & "D2:" & D & j & ")"
Dim patid1 As String
patid1 = "ws_multidax.Range(" & "D2:" & D & lastFullRow2 & ")"
With ws_mainfile
Dim commandstring As String
'The formula we want is a concatenated string
commandstring = "{=INDEX(" & firstArgument & ",MATCH(1,(" & secondArgument & "=" & condition1 & ")*(" & thirdArgument & "=" & condition2 & ")*(" & patid1 & "=" & condition3 & "),0))}"
'Insert the formula into each cell as the loop goes down the rows
ws_mainfile.Range("AN" & j).Formula = Eval(commandstring)
'ws_mainfile.Range("AN" & j).Formula = commandstring
End With
Next j
The #Value! gets put into the cells when I run the line with the Eval(commandstring). When I run the line with just formula = commandstring, the formula gets put in each cell, but it does not solve.
Your code has 2 problems:
You are putting in the curly braces of an array formula manually, don't do this
You are putting in an array formula as a regular formula
So to correct, do the following:
'1. Change this line:
commandstring = "{=INDEX(....)}"
'And simply remove the curly braces {} from its beginning and end
commandstring = "=INDEX(....)"
'2. Change this line:
ws_mainfile.Range("AN" & j).Formula = Eval(commandstring)
'To use the .FormulaArray property instead of just .Formula:
ws_mainfile.Range("AN" & j).FormulaArray = commandstring
You're on the right track. There's no need to use the eval function, as you have built a string formula in code. The problem is you have surrounded it with the braces, which excel treats as if you had entered text.
Try this instead:
commandstring = "=INDEX(" & firstArgument & ",MATCH(1,(" & secondArgument & "=" & condition1 & ")*(" & thirdArgument & "=" & condition2 & ")*(" & patid1 & "=" & condition3 & "),0))"
'Insert the formula into each cell as the loop goes down the rows
ws_mainfile.Range("AN" & j).Formula = commandstring