Using Excel VBA I am writing records to a DB2 data file.
A field that holds the description is 80 characters.
Data format is recseq, etqindx, seqno, description.
My Description string may be several hundred characters.
I want to loop thru the string and write a record for each 80 characters.
This is as far as I have got.
On Error Resume Next
logindex2 = (Now() - #1/1/1970#) * 86400000
recInsert = "Insert Into webprddt1.wqmsnxtid" & _
"(recseq, crtdt) Values(" & logindex2 & ",current_timestamp)"
oConn.Execute (recInsert)
seqno = 1
Do
oConn.Execute "Insert Into webprddt1.wqmsetqd1(recseq,etqindx,seqno,descriptn)" _
& "Values(" & logindex2 & "," & logindex & "," & seqno & ",'" & ncDescription & "')"
Loop Until IsEmpty(ncDescription)
This should break it down: (You did not provide the whole Sub/Function, other details may cause an issue)
On Error Resume Next
logindex2 = (Now() - #1/1/1970#) * 86400000
recInsert = "Insert Into webprddt1.wqmsnxtid" & _
"(recseq, crtdt) Values(" & logindex2 & ",current_timestamp)"
oConn.Execute (recInsert)
seqno = 1
Dim rString As String, cString As String
rString = ncDescription
Do While Len(rString) >= 80
'Get 80 Left Characters
cString = Left(rString, 80)
'Remove the 80 Characters for the next loop
rString = Right(rString, (Len(rString) - 80))
oConn.Execute "Insert Into webprddt1.wqmsetqd1(recseq,etqindx,seqno,descriptn)" _
& "Values(" & logindex2 & "," & logindex & "," & seqno & ",'" & cString & "')"
seqno = seqno + 1
Loop
'If there is anything remaining in the string do a final insert
If Len(rString > 0) Then
cString = rString
oConn.Execute "Insert Into webprddt1.wqmsetqd1(recseq,etqindx,seqno,descriptn)" _
& "Values(" & logindex2 & "," & logindex & "," & seqno & ",'" & cString & "')"
End If
Related
I have the following issue: I create a chart from values that a user will insert in specific cells of a spreadsheet and the chart displays what I expect (The series are collected in the right way). The Series are created consecutively with 2 data points only. I want to store the Xvalues (And YValues) of the series in dynamic arrays for performing calculations later (outside the series collection loop). I tried the following but the arrays only store the last values of the Series (despite using redim preserve everywhere).
Is it because the array is not redimensioned correctly?
Thanks for your help!
i = 1
SeriesAddedA = 1
RangeOccupiedA = Range("A2").End(xlDown).Row
RangeOccupiedB = Range("B2").End(xlDown).Row
MaxRangeOccupied = WorksheetFunction.Max(RangeOccupiedA, RangeOccupiedB)
Dim XValuesA()
Dim YValuesA()
ReDim XValues(RangeOccupiedA + 2)
ReDim YValues(RangeOccupiedA + 2)
Do While i < MaxRangeOccupied
FilledCompA = NextFilled(Cells(i, 1))
PrevCell = PrevFilled(Cells(i + 1, 1))
rowdiff = FilledCompA - PrevCell
If rowdiff < 2 And PrevCell <> 0 And FilledCompA <> 0 Then
ReDim Preserve XValuesA(1 To RangeOccupiedA + 2)
chart.SeriesCollection.NewSeries
chart.FullSeriesCollection(SeriesAddedA).Name = "Reaction Step A " & SeriesAddedA - 1
chart.FullSeriesCollection(SeriesAddedA).XValues = "=" & "'" & ActiveSheet.Name & "'" & "!$E$" & FilledCompA - 1 & ":$E$" & FilledCompA
chart.FullSeriesCollection(SeriesAddedA).Values = "=" & "'" & ActiveSheet.Name & "'" & "!$M$" & FilledCompA - 1 & ":$M$" & FilledCompA
XValuesA() = chart.SeriesCollection(SeriesAddedA).XValues
SeriesAddedA = chart.SeriesCollection.Count + 1
ElseIf PrevCell <> 0 And rowdiff > 0 Then
ReDim Preserve XValuesA(1 To RangeOccupiedA + 2)
chart.SeriesCollection.NewSeries
chart.FullSeriesCollection(SeriesAddedA).Name = "Reaction Step prev A " & SeriesAddedA - 1
chart.FullSeriesCollection(SeriesAddedA).XValues = "=" & "(" & "'" & ActiveSheet.Name & "'" & "!$E$" & FilledCompA - rowdiff & "," & "'" & ActiveSheet.Name & "'" & "!$E$" & FilledCompA & ")"
chart.FullSeriesCollection(SeriesAddedA).Values = "=" & "(" & "'" & ActiveSheet.Name & "'" & "!$M$" & FilledCompA - rowdiff & "," & "'" & ActiveSheet.Name & "'" & "!$M$" & FilledCompA & ")"
XValuesA() = chart.SeriesCollection(SeriesAddedA).XValues
SeriesAddedA = chart.SeriesCollection.Count + 1
End If
loop
'the debug print says:
XvaluesA(1) 310.52
XvaluesA(2) 408.58
With XValuesA() = chart.SeriesCollection(SeriesAddedA).XValues you overwrite the data in XValuesA everytime you call it in your loop. That is why it only contains the last values.
Use XValuesA(i) = chart.SeriesCollection(SeriesAddedA).XValues instead and then
Debug.Print XvaluesA(1)(1)
Debug.Print XvaluesA(1)(2)
gives the first values and
Debug.Print XvaluesA(2)(1)
Debug.Print XvaluesA(2)(2)
the second …
Below is my code that I am trying to append new text to an existing comment. However, when I execute, it is spitting an error - "Application defined/Object defined error". Could someone help?
For Each c In Range("G" & iCellIndex)
If StrComp(JSONObj2("fields")("worklog")("worklogs")(j + 1)("author")("displayName"), Range("G" & iCellIndex).Value) = 0 Then
Set cmt = ActiveCell.AddComment
cmt.Comment.Text iTimeStamp & "--" & JSONObj2("fields")("worklog")("worklogs")(j + 1)("timeSpent") , 1, False
Range("G" & iCellIndex).AddComment iTimeStamp & "--" & JSONObj2("fields")("worklog")("worklogs")(j + 1)("timeSpent") , 1, False
End If
iCellIndex = iCellIndex + 1
Next c
For those interested, this is how I fixed the issue:
If StrComp(JSONObj2("fields")("worklog")("worklogs")(j + 1)("author")("displayName"), Range("G" & iCellIndex).Value) = 0 Then
Range("G" & iCellIndex).NoteText Text:=Range("G" & iCellIndex).NoteText & Chr(10) & iTimeStamp & " -- " & JSONObj2("fields")("worklog")("worklogs")(j + 1)("timeSpent") & Chr(10)
End If
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'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"")"
I have a "large" SQL query (like 200 lines)...
dim query as string
query = "..................................." & _
"..................................." & _
.... Like a lot lines later...
"..................................."
function query,"sheet 1"
When I do this, Excel says "Too many line continuations."
What is the best way to avoid this?
There's only one way -- to use less continuations.
This can be done by putting more text on a line or by using concatenation expressed differently:
query = ".........."
query = query & ".........."
query = query & ".........."
But the best is to load the text from an external source, as a whole.
Split the query into several sections:
query = _
"............" & _
"............" & _
"............"
query = query & _
"............" & _
"............" & _
"............"
query = query & _
"............" & _
"............" & _
"............"
So far I found this...
Call AddToArray(query, "...")
Call AddToArray(query, "...")
... a lot lines later...
Call AddToArray(query, "...")
*edit: Forgot to add:
Sub AddToArray(myArray As Variant, arrayElement As Variant)
If Not IsArrayInitialized(myArray) Then
ReDim myArray(0)
myArray(0) = arrayElement
Else
ReDim Preserve myArray(UBound(myArray) + 1)
myArray(UBound(myArray)) = arrayElement
End If
End Sub
Source: link text
X( thankyou
(Still waiting for better ways to do this...) thankyou :P
why not use VBA to help with the VBA concatenation?
Check this code of mine (it is very primitive and feel free to adjust it), it basically takes whatever data you have on worksheet called "Fast_string" in columns "A:E" and in column F it prepares you the code for the concatenation using preliminary variable "prelim_string". You just use this and then copy-paste the solution from column F into your code... you're welcome ;)
Sub FAST_STRING()
Dim cel As Range, lastcel As Range, prel_r As String, i As Integer, cr As Integer
With ThisWorkbook.Worksheets("Fast_string")
Set lastcel = .Cells(10000, 1).End(xlUp)
For Each cel In .Range(.Cells(1, 1), lastcel)
cr = cel.row
prel_r = ""
For i = 1 To 5
If .Cells(cr, i) = "" Then
prel_r = prel_r & " "
Else
prel_r = prel_r & " " & Replace(.Cells(cr, i).Value, """", """""")
End If
Next i
If cr = 1 Then
prel_r = "Prelim_string =" & """" & prel_r & """" & " & chr(10) & _"
ElseIf cr / 20 = Round(cr / 20) Then
prel_r = "Prelim_string = Prelim_string & " & """" & prel_r & """" & " & chr(10) & _"
Else
prel_r = """" & prel_r & """" & " & chr(10) & _"
End If
If cr = lastcel.row Or (cr + 1) / 20 = Round((cr + 1) / 20) Then prel_r = Left(prel_r, Len(prel_r) - 14)
cel(1, 6) = prel_r
Next cel
End With
End Sub