One line of code in Loop gives undesirable results - loops

The code below copies the values of the selected record to all records on my form.
But, this line in the code is giving me undesirable results
.Fields("ResultsID").Value = Me.TestResultID.Value
Instead of copying the TestResultIDs of each record into ResultsID, it makes all ResultsID the same as the selected record's TestResultsID.
Where would be the best place to move that line of code to?
With Me.RecordsetClone
.MoveFirst
Do While .EOF = False
If .Fields("[Ordered Analyte]").Value = Me.[Ordered Analyte].Value Then
.Edit
.Fields("DateStarted").Value = Me.DateStarted.Value
.Fields("TimeStarted").Value = Me.TimeStarted.Value
.Fields("DateCompleted").Value = Me.DateCompleted.Value
.Fields("TimeCompleted").Value = Me.TimeCompleted.Value
.Fields("Result").Value = Me.Result.Value
.Fields("Count").Value = Me.[txtCount].Value
.Fields("ResultsID").Value = Me.TestResultID.Value
.Update
End If
.MoveNext
Loop
End With

replace
.Fields("ResultsID").Value = Me.TestResultID.Value
with
.Fields("ResultsID").Value = .Fields("TestResultsID").Value
to use the TestResultsID from each individual record instead of just the current one.

The code below copies the values of the selected record to all records
on my form.
and:
it makes all ResultsID the same as the selected record's TestResultsID.
Thus, your code works exactly as intended.

Related

VBA loop works using F8 but not when running free

I realise these errors are unique to the code written so no previous examples have helped much, except I can report that I do trap any errors, and none show up. The procedure is long but here is the part that is being missed out in realtime.
...With rsFacilityStock
.Edit
!TotalShares = !TotalShares + rsPending!Shares
Select Case rsPending!BuySell
Case BUY_STOCK
strTradeType = "BUY"
lngMovementID = MOVEMENT_PURCHASE
Case PARTSELL_STOCK, SELL_STOCK
If rsPending!BuySell = PARTSELL_STOCK Then
strTradeType = "PSALE"
Else
strTradeType = "SALE"
**!Archived = True
!ArchiveDate = rsPending!PurchaseDate**
End If
'Build Array for clearing out sharesleft
intSaleCount = intSaleCount + 1
ReDim Preserve SaleRecord(1 To intSaleCount)
With SaleRecord(intSaleCount)
.FacilityStockID = rsPending!FacilityStockID
.TradeDate = rsPending!PurchaseDate
.SharesTraded = rsPending!Shares
End With
Case 4
strTradeType = "ROLLO"
booCashPot = False
End Select
.Update
End With...
The part between the ** is what fails when the trade is a Sale. I note that the strTradeType does get set but the Archiving fails. My suspicion is that it is the .Update that is failing. Just don't know why. Ideas welcome.

LUA script: Nested loop inserts only last item

I have two loops, a main loop and a sub-loop inside the main loop. Both loops populate the same table (and sub-table). But for some reason the sub-loop only stores the last added item in the nested table.
For instance, main group 1 has sub-groups stored as 1-9:
printTable(data[1][subItems][1]) -- returns error (index nil value)
printTable(data[1][subItems][9]) -- dumps table to console
If I break the sub-loop after one iteration then data[1][subItems][1] contains data
for i=startId, endId, 10 do
items = loadItems(i)
data[i] = {['items'] = items}
for x=i+1, i+10-1 do
subItems = loadItems(x)
print('adding items to sub-group: '..x..' for main group: '..i)
data[i]['subItems'] = {}
data[i]['subItems'][x] = {['items'] = subItems}
end
end
end
Since I'm printing some debug info inside the sub-loop, I know that, the code is being executed. And I know that loadItems(x) is getting the data on each iteration, because if i dump the loadItems(x) to console in the sub-loop, all is there on each iteration.
What is this wizardry?
Silly me, how could I miss it!
The answer is of course to move the data[i][subItems] = {} outside the sub-loop:
for i=startId, endId, 10 do
items = loadItems(i)
data[i] = {['items'] = items}
data[i]['subItems'] = {} <----------------------------------------------
for x=i+1, i+10-1 do
subItems = loadItems(x)
print('adding items to sub-group: '..x..' for main group: '..i)
data[i]['subItems'][x] = {['items'] = subItems}
end
end
end

Check code in loop doesn't working properly

I made a code capable of downloading values in a web page and it works well. Since the values are taken in real time, that is, data download is performed only when there are actually changes, I need if a certain value is changed.
I then created a code that allows me to get check from all elements of the array with the updated values and the array with the old values.
The code actually detects when a given result has changed, but for some strange reason, the message appears to infinity, as if it were stuck in a foor that takes no arguments, and this is very strange.
For Each abc As Country_Data In lista
For Each xyz As Country_Data In vecchia_lista
If abc.casa = xyz.casa And abc.ospite = xyz.ospite Then
If abc.Result <> xyz.Result Then
MsgBox(abc.casa & " - " & abc.ospite & " -- " & abc.Result)
Exit For
End If
End If
Next
Next
Variable definition
Dim lista As New List(Of Country_Data)
Dim vecchia_lista As New List(Of Country_Data)
Private Structure Country_Data
Dim casa As String
Dim ospite As String
Dim Result As String
End Structure
how to fix this?
Based on your comments, I'm gathering that you only ever want to see one message box, when it finds the first case where a result has changed (even though there could be others after that).
The Exit For you're using only exits from the inner For loop, and thus the outer For loop continues to loop, which is probably what you're observing.
You can do something like this:
Dim keepLooping As Boolean = True
For Each abc As Country_Data In lista
For Each xyz As Country_Data In vecchia_lista
If abc.casa = xyz.casa And abc.ospite = xyz.ospite Then
If abc.Result <> xyz.Result Then
MsgBox(abc.casa & " - " & abc.ospite & " -- " & abc.Result)
keepLooping = False
Exit For
End If
End If
Next
If (Not keepLooping) Then Exit For
Next
That way when you want to stop looping, it will set the boolean flag and that will be observed by the outer loop, causing it to exit as well.

VB.Net : Create a Recordset with manual inputs and GetRows() methods failing

First time writing on a forum but this one really left me no choice and it seems that nobody had the same problem as I have... not a good sign...
I have a project to use the COM Server of a software we use internally and need to use one of their built-in function which requires a recordset as an input and return another recordset with the results (important because I need to stick with the recordset).
Here's breifly what I tried. I create a recordset from scratch and fill it with some hardcoded data just for testing purposes. Once my recordset is filled, I want to look at the data just to be sure everything works well, but I'll have to do the same eventually with my results.
The problem I get is it seems that the GetRows() method return only 1 row every time depending on the last row I moved to. But once it's called, I cannot get the other records. I'm already using the GetRows() method with an actual query and still with an ADODB recordset and it works perfectly. Building a recodset from scratch seems less easy.
I need to put all my data in an object to work with it. But even if I want to use only a recordset, I cannot access to all data in it. Very fustrating... something I'm missing here...
Error I get: either bof or eof is true or the current record has been deleted
Thanks in advance,
Public Function GetFDBData() As Boolean
Dim filtersView As New ADODB.Recordset
Dim rsFields(1) As Object
Dim fieldsAPT(3, 1) As Object
Dim dataView As Object
Dim i As Integer
rsFields(0) = "Field Name"
rsFields(1) = "Filter"
fieldsAPT(0, 0) = "ISIN"
fieldsAPT(0, 1) = "=CA89*"
fieldsAPT(1, 0) = "Currency"
fieldsAPT(1, 1) = "=CAD"
fieldsAPT(2, 0) = "Line"
fieldsAPT(2, 1) = "=Bond"
fieldsAPT(3, 0) = "Redemption Date"
fieldsAPT(3, 1) = "=20230*"
Try
'Build the recordset containing APT fields and filters (in the same variable fieldsAPT)
filtersView.CursorLocation = ADODB.CursorLocationEnum.adUseClient
filtersView.Fields.Append(rsFields(0), ADODB.DataTypeEnum.adVarChar, 30)
filtersView.Fields.Append(rsFields(1), ADODB.DataTypeEnum.adVarChar, 30)
filtersView.Open(, , ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockOptimistic)
Dim fieldAPT(1)
For i = 0 To UBound(fieldsAPT)
fieldAPT(0) = fieldsAPT(i, 0)
Console.WriteLine(fieldAPT(0)) 'Works fine
fieldAPT(1) = fieldsAPT(i, 1)
Console.WriteLine(fieldAPT(1)) 'Works fine
filtersView.AddNew(rsFields, fieldAPT)
filtersView.Update()
Console.WriteLine(filtersView.RecordCount) 'I can see 1 2 3 4 no problem here
Next i
Dim xx As Integer = filtersView.RecordCount 'xx is 4 as expected
Console.WriteLine("xx: " & xx)
filtersView.MoveFirst() 'Will move to the first record or whatever record
'dataView = filtersView.GetRows() 'I expected this line to work, but same results
For i = 0 To xx - 1
dataView = filtersView.GetRows()
Console.WriteLine(dataView(i, 0).ToString) 'ISIN, normal
Console.WriteLine(filtersView.RecordCount) 'Still equals 4, normal
Console.WriteLine(filtersView.BOF) 'False, normal
Console.WriteLine(filtersView.EOF) 'True, which is NOT normal
Console.WriteLine(filtersView.AbsolutePosition) 'Get -3 not sure why (position 1 related to 4???)
Console.WriteLine(filtersView.MaxRecords) 'Get 0 not sure why
filtersView.MoveNext() '!!!! Here is where it fails !!!! Cannot go more than i=0
Next i
GetFDBData = True
Catch ex As Exception
MsgBox(ex.Message)
GetFDBData = False
Finally
'Clear memory
filtersView.Close()
End Try
End Function
Also, if I do this,
Dim xx As Integer = filtersView.RecordCount 'xx is 4 as expected
Console.WriteLine("xx: " & xx)
filtersView.MoveLast()
Instead of
Dim xx As Integer = filtersView.RecordCount 'xx is 4 as expected
Console.WriteLine("xx: " & xx)
filtersView.MoveFirst()
It will return "Redemption date" in the for loop after. Which makes sense because it is the last record. But puting movefirst even after does'nt solve the issue... still one row only. So the data is there, but I really can't extract one line and one line only...
Try changing your cursor type to adOpenDynamic
EDIT: OK,your line
dataView = filtersView.GetRows()
is causing your cursor to travel to the end of the recordset, try moving it outside your loop and following it with a new MoveFirst like so
filtersView.MoveFirst() 'Will move to the first record or whatever record
'dataView = filtersView.GetRows() 'I expected this line to work, but same results
dataView = filtersView.GetRows()
filtersView.MoveFirst()
Dim sTemp As String = ""
For i = 0 To xx - 1
'Console.WriteLine(dataView(i, 0).ToString) 'ISIN, normal
Console.WriteLine(filtersView.RecordCount) 'Still equals 4, normal
Console.WriteLine(filtersView.BOF) 'False, normal
Console.WriteLine(filtersView.EOF) 'True, which is NOT normal
Console.WriteLine(filtersView.AbsolutePosition) 'Get -3 not sure why (position 1 related to 4???)
Console.WriteLine(filtersView.MaxRecords) 'Get 0 not sure why
sTemp = sTemp & "(" & dataView(0, i).ToString & ", " & dataView(1, i).ToString & ")"
filtersView.MoveNext() '!!!! Here is where it fails !!!! Cannot go more than i=0
Next i
Console.WriteLine(sTemp)
You can verify that by checking the value of filtersView.AbsolutePosition immediately before and after your call to GetRows
Also, you are reversing rows and columns in dataView, move i to the second subscript position. I put it in a temporary string to make it easier to view in the debugger.

Nested loop conditional

Supposed I have this table:
TDID TDLINE
F04 04-AA
F04 04-BB <-- call a function
F05 05-AA
F05 05-BB <-- call a function
F06 06-AA <-- call a function
I would like to call a function while the TDID field is not the same as the previous one. I have the code below, it works but somehow it's not perfectly works (it missed the last row):
LOOP AT lines ASSIGNING <fs1>.
IF <fs2> IS INITIAL.
<fs2> = <fs1>.
ELSE.
li_line-tdline = <fs2>-tdline.
APPEND li_line.
IF <fs1>-tdid NE <fs2>-tdid.
li_thead-tdid = <fs2>-tdid.
CALL FUNCTION 'SAVE_TEXT'
EXPORTING
header = li_thead
savemode_direct = 'X'
TABLES
lines = li_line
CLEAR: li_thead,
li_line.
FREE: li_thead,
li_line.
ENDIF.
ENDIF.
ENDLOOP.
ANSWER
Thank you to vwegert for the answer:
LOOP AT lines ASSIGNING <fs1>.
AT NEW tdid.
REFRESH li_thead.
REFRESH li_line.
li_thead-tdid = <fs1>-tdid.
APPEND li_thead.
ENDAT.
li_line-tdline = <fs1>-tdline.
APPEND li_line.
AT END OF tdid.
CALL FUNCTION 'SAVE_TEXT'
EXPORTING
header = li_thead
savemode_direct = 'X'
TABLES
lines = li_line
ENDAT.
ENDLOOP.
Assuming that the table is sorted by TDID and no field left of TDID changes more frequently than TDID:
LOOP AT lines ASSIGNING <fs1>.
AT NEW tdid.
REFRESH some_other_tab.
ENDAT.
APPEND <fs1> TO some_other_tab.
AT END OF tdid.
CALL FUNCTION ...
ENDAT.
ENDLOOP.
The unpredictability as mentioned by vwegert comes because the characters fields next to the field on which Control statement is applied are converted to asterisks(*). If you want to use these values in the control statement make sure you copy the values in a temporary table and loop on it instead of the original internal table and use the values using READ on the original internal table. Also keep in mind that control statement considers all columns to the left of the column being used in the statement for it's condition.

Resources