Nested loop conditional - loops

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.

Related

Table[1] returning nil when table does exist and has values

local mapSpawnsData = {}
local JSONData = file.Read(filePath) -- read file as json text
mapSpawnsData = util.JSONToTable(JSONData) -- convert JSON to table
print("TABLE:")
PrintTable(mapSpawnsData)
print("TABLE[1]:")
print(tostring(mapSpawnsData[1]))
This is a script for a game called garrysmod. PrintTable() is a function I can call included in the game.
The code snippet I included returns this: (Same output if I remove the tosring())
TABLE:
gm_construct:
1 = -1303.524902 167.472397 -44.081600
2 = 1250.890137 331.746185 -44.081600
3 = 674.012085 223.775604 -32.148102
TABLE[1]:
nil
I expected to get back "gm_construct". What am I missing here?
What you didn't notice is that PrintTable printed gm_construct: first and then 1 = .
That means the table actually contains only gm_construct key with a table with 3 keys.
To be able to always read PrintTable output properly look at the ident. 1 = is tabulated to the right once, this means they are keys of something nested in the table you initially printed.
If this still confuses you, try to run this:
for k,v in pairs(mapSpawnsData) do
print(k, "=", v)
end
This won't print nested content.
To make your code work do mapSpawnsData.gm_construct[1] or mapSpawnsData["gm_construct"][1]

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

One line of code in Loop gives undesirable results

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.

navision- looping through line nos in sales line

i am trying to retrieve the difference of qty and qts shipped for a sales order.
i am doing this through code.
setting range on sales line table fields and using findset does loop through all lines properly but while printing it gives the difference frm the last line.
clearing the variable is also not working.
i am new to NAV 2013 so not able to find out how to loop through all this lines so that it displays result properly.i tried using findfirst inside the if loop but no success.
You need to add to "Value", not overwrite it. (use +=, not :=)
CLEAR(Value);
SalesLine.RESET;
SalesLine.SETRANGE(SalesLine."Document No.","No.");
IF SalesLine.FINDSET THEN REPEAT
Value += SalesLine.Quantity - SalesLine."Quantity Shipped";
//MESSAGE('%1',Value);
UNTIL SalesLine.NEXT =0;
Try this code
local procedure DailyCalc(DailyLotNumber: Query DailyLotNumber): Decimal
var
SalesLine: Record "Sales Line";
NewRec: Decimal;
begin
SalesLine.SetRange("Document No.", DailyLotNumber.No_);
SalesLine.SetRange("Document Type", DailyLotNumber.Document_Type);
if SalesLine.FindSet() then begin
repeat
repeat
NewRec += (SalesLine.Quantity - SalesLine."Quantity Shipped") * SalesLine."Unit Price";
until SalesLine.Next() = 0;
exit(NewRec);
until SalesLine.Next() = 0;
end;
end;

How to index a table automatically and loop it in ipairs while keeping all data?

Table:
localization_strings = {
string_1 = "Text Here",
string_2 = "Some More Text Here",
string_3 = "More Text"
}
This is obviously not the whole table, but just a small sample. The real table is over 500+ lines. The reason I don't just redo the table is because other functions reference it and I don't have access to those files to fix them, so I have to find a work around. Also, because it would quite tedious work and can cause problems with other codes.
I have made 2 attempts at solving this problem, but I can only get one of the values I want (incorrect terminology, I think) and I need both as 1 is display text and 1 is data for a function call.
Attempts:
-- Attempt #1
-- Gives me the string_#'s but not the "Text"...which I need, as I want to display the text via another function
LocalizationUnorderedOpts = {}
LocalizationOpts = {}
for n,unordered_names in pairs(localization_strings) do
if (unordered_names) then
table.insert( LocalizationUnorderedOpts, n)
end
end
io.write(tostring(LocalizationUnorderedOpts) .. "\n")
table.sort(LocalizationUnorderedOpts)
for i,n in ipairs(LocalizationUnorderedOpts) do
if (n) then
io.write(tostring(i))
table.insert( LocalizationOpts, { text = tostring(LocalizationUnorderedOpts[i]), callback = function_pointer_does_not_matter, data = i } )
end
end
-- Attempt #2
-- Gives me the "Text" but not the string_#'s...which I need to as data to the callback to another function (via function pointer)
LocalizationUnorderedOpts = {}
LocalizationOpts = {}
for n,unordered_names in pairs(localization_strings) do
if (unordered_names) then
table.insert( LocalizationUnorderedOpts, localization_strings[n])
end
end
io.write(tostring(LocalizationUnorderedOpts) .. "\n")
table.sort(LocalizationUnorderedOpts)
for i,n in ipairs(LocalizationUnorderedOpts) do
if (n) then
io.write(tostring(i))
table.insert( LocalizationOpts, { text = tostring(LocalizationUnorderedOpts[i]), callback = function_pointer_does_not_matter, data = i } )
end
end
If I understand it correctly, you need to sort the non-array table. Your first attempt has done most of the work: build another table, which has the values the same as the keys in the original table.
What's left is how to get the original values like "Text Here", for that you need to index the original table:
for k, v in ipairs(LocalizationUnorderedOpts) do
print(v) --original key
print(localization_strings[v]) --original value
end

Resources