Forum > Beginners
Dynamic array empty elements issue
noszone:
I have a dynamic array of record data type, like:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---id:largeint,empid:largeint,description:string
I am fetching data from db and making output to xlsx file.
In loop process there, when writing values to array there is always "empty" elements, let say the real data length must be 700 due of an IF condition of data filtering. While total loop count increases array length up to 7000 and contains empty elements.
But if I wisely use the increment, something like:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---if ..... thensetlength(array, length(array)+1)...write values to arrayinc(k)
So there will be no empty elements. And I can use that data very well.
So same IF condition(when taking completed array and starting output to xlsx) doesn't work well with 1st case. It looks like due of holes, the data in output xlsx file reduced to 20% only. I miss 80% of data somewhere.
If condition(just filtering array before send to xlsx):
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---for j:=0 to Length(cert_d)-1 do beginif (emp_v[i].id=cert_d[j].empid) and (cert_v[cert_count].id=cert_d[j].id) then begin...Output to xlsx
j-the array loop, i-employee loop, cert_count-emp certificates type loop.
This is really strange, due loop goes to each element, even if the length of array is 7000 with some empty elements...
What problem this can be?
TRon:
I had two large coffee now (to try and wake up) and I'm sorry to say that I still don't understand your explanation(s) or what it is that you are trying to achieve. Perhaps I just woke up dumb this morning (happens on occasion, not your fault) :)
So far I got:
1 database with let's say million's of record
2. database is filtered so that there are 700 filtered results.
3. you have a loop that counts to 7000 and with each iteration increases the length of an array
4. as a consequence your array contains empty elements ?
I fail to see the connection between 700 database records vs 7000 array elements and what you are trying to copy and what exactly from where to where . Your code-snippets are not very helpful in that regards.
I have no idea what the current situation is, let alone what the problem could be.
Could you please share some more code and explain the connection between the different items that you speak of ? (nr of db records, nr of array elements, j-the array loop, i-employee loop, cert_count-emp certificates type loop).
howardpc:
As with all posts asking for help debugging an app, the simplest compilable project that shows the problem is essential for others to comment intelligently.
Otherwise the thread becomes random shots in the dark, guesses (which might be inspired) mixed with contributions which later are seen to be irrelevant simply because the original question is imprecise or incomplete.
Code snippets shown are usually less than a few percent of the entire project's code, and forum members are expected to somehow crystal ball what is not shown.
Thaddy:
--- Quote from: TRon on February 06, 2023, 07:14:30 am ---3. you have a loop that counts to 7000 and with each iteration increases the length of an array
--- End quote ---
No, that is not how real databases work. They work more akin to Pascal sets. Filtering can be done in O(1). And Pascal is the perfect way to demonstrate that since it has native set support. Although limited in size, Pascal sets demonstrate the principle. Together with Venn diagrams to visualize filtering. No loops. In theory. Filters are masks, not loops.
noszone:
I am sorry for the luck of code, here is the function which generates array:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TForm1.GetDataFromDb_Cert(SelEmp:DataTypeEmp;SelItems:DataType):DocumentDataType;var i,j,k,count:integer;typeid,empid,issued,expired:TField;begink:=0;SQLQuery5.Close;SQLQuery5.Clear;SQLQuery5.sql.add('select EMPLOYEEID,EMPLICENSETYPEID,ISSUEDDATE,EXPIRYDATE '+'from spectwosuite.emplicense where '+'internalstatus<>70 and internalstatus<>0');SQLQuery5.Open;SQLQuery5.Last;SQLQuery5.First;empid:=SQLQuery5.FieldByName('EMPLOYEEID');typeid:=SQLQuery5.FieldByName('EMPLICENSETYPEID');issued:=SQLQuery5.FieldByName('ISSUEDDATE');expired:=SQLQuery5.FieldByName('EXPIRYDATE'); for i:=0 to length(SelEmp)-1 do begin //main emp. loop for count:=0 to length(SelItems)-1 do begin //certs SQLQuery5.First;for j:=0 to SQLQuery5.RecordCount-1 do beginif (typeid.AsLargeInt=SelItems[count].id) and(empid.AsLargeInt=SelEmp[i].id) then beginSetLength(cert_d,Length(cert_d)+1);cert_d[k].id:=typeid.AsLargeInt;cert_d[k].empid:=empid.AsLargeInt;cert_d[k].description:=SelItems[count].description;cert_d[k].date_issued:=issued.asstring;cert_d[k].date_expired:=expired.asstring;debug_file.WriteAnsiString(inttostr(cert_d[k].empid)+' '+ inttostr(cert_d[k].id)+selEmp[i].surname+cert_d[k].description+' '+cert_d[k].date_expired);debug_file.WriteByte(13);inc(k); end; SQLQuery5.Next;end; end; end;result:=cert_d;end;
As you can see, here I've used an increment, so no holes in arrays(the program now working 100%, but I want to know why with empty elements it doesn't work properly).
And here is types:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---type DocumentDataRecord=record id:largeint; empid:largeint; description:string; date_issued:string; date_expired:string; end; DocumentDataType=array of DocumentDataRecord; DataRecord=record id:largeint; description:string; end; DataType=array of DataRecord; DataRecordEmp=record id:largeint; surname:string; forename:string; position:string; end; DataTypeEmp=array of DataRecordEmp;
So after function GetDataFromDb_Cert array of records goes to above IF condtion and goes to excel:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---for i:=0 to length(emp_v)-1 do begin MyWorksheet.WriteText(i+ExcelRowShift, 0, emp_v[i].surname+' '+emp_v[i].forename);MyWorksheet.WriteBorders(i+ExcelRowShift, 0, [cbNorth, cbSouth,cbWest, cbEast]);MyWorksheet.WriteText(i+ExcelRowShift, 1, emp_v[i].position);MyWorksheet.WriteBorders(i+ExcelRowShift, 1, [cbNorth, cbSouth,cbWest, cbEast]);MyWorksheet.WriteRowHeight(ExcelRowShift-1,ExcelHeaderRowHeight,suMillimeters); for cert_count:=0 to Length(cert_v)-1 do begin if i=0 then beginMyWorksheet.WriteWordwrap(ExcelRowShift-1,cert_count+ExcelColShift,true);MyWorksheet.WriteHorAlignment(ExcelRowShift-1, cert_count+ExcelColShift, haCenter);MyWorksheet.WriteVertAlignment(ExcelRowShift-1, cert_count+ExcelColShift, vaCenter);MyWorksheet.WriteFontStyle(i+ExcelRowShift-1, cert_count+ExcelColShift,[fssBold]);MyWorksheet.WriteBorders(i+ExcelRowShift-1, cert_count+ExcelColShift, [cbNorth, cbSouth,cbWest, cbEast]);MyWorksheet.WriteText(i+ExcelRowShift-1, cert_count+ExcelColShift, cert_v[cert_count].description);end; for j:=0 to Length(cert_d)-1 do beginif (emp_v[i].id=cert_d[j].empid) and (cert_v[cert_count].id=cert_d[j].id) then beginMyWorksheet.WriteText(i+ExcelRowShift, cert_count+ExcelColShift, cert_d[j].date_expired);MyWorksheet.WriteBorders(i+ExcelRowShift, cert_count+ExcelColShift, [cbNorth, cbSouth,cbWest, cbEast]); if length(cert_d[j].date_expired)<>0 then begin cmp:=comparedate(strtodate(cert_d[j].date_expired),test_date); if cmp<0 then MyWorksheet.WriteBackgroundColor(i+ExcelRowShift,cert_count+ExcelColShift, clRed); end;{Inc(FProgress);StatusBar1.Panels.Items[1].Text := IntToStr(FProgress); //init a redrawApplication.ProcessMessages;}endelse beginMyWorksheet.WriteBorders(i+ExcelRowShift, cert_count+ExcelColShift, [cbNorth, cbSouth,cbWest, cbEast]);end; end; end; end;MyWorkbook.WriteToFile(MyDir + 'CO-HSE-Matrix.xls', sfExcel8, true);
Navigation
[0] Message Index
[#] Next page