Page 1 of 1
SortStructuredArray Problems
Posted: Sun Jun 21, 2009 11:41 pm
by trather
I very much like and use PB for a number of small applications to make things easier but I am having problems with the following code. I can load the array and get the data out of the array fine but when I go to sort it I get nothing out. The data is wiped from the array.
Code: Select all
Structure EmailData
FullName.s
Eid.s
Size.s
E_Server.s
Marsha.s
Domain.s
Dept.s
EndStructure
Global Dim Exchange.EmailData(1000)
;Loop to load the data in
Exchange(Counter)\FullName = Name$
Exchange(Counter)\Eid = EID$
Exchange(Counter)\Size = StrF(MG_Size,2)
Exchange(Counter)\E_Server = Server$
Exchange(Counter)\Marsha = Marsh$
Exchange(Counter)\Domain = Domain$
Exchange(Counter)\Dept = Department$
SortStructuredArray(Exchange(), 0, OffsetOf(EmailData\FullName), #PB_Sort_String)
When I take the Sortstructured command out I can get the data out to the the file but when I sort it it appeard to be deleted.
Posted: Sun Jun 21, 2009 11:56 pm
by djes
Try to initialise all your strings with ""
Posted: Mon Jun 22, 2009 12:33 am
by netmaestro
You'll need to remove any empty array elements. If your array wasn't full all the first entries will be blank and it'll look like your data was destroyed. You can also employ the optional start/end parameters if you know how many entries were read in. Possibly do a redim, etc.
Blank
Posted: Mon Jun 22, 2009 1:46 am
by trather
I thought that it might be something like that so I took the data and wrote it to a file and the array was really gone. There was nothing but the counters that I put in just to make sure that it was writing data to the file.
Also I have tried to set the whole structure to null and that also didn't work.
I am using PB version 4.30
Posted: Mon Jun 22, 2009 1:49 am
by netmaestro
iirc there was a bug in 4.30 for SortStructuredArray. Upgrade to 4.31 final and the problem should be gone.
Upgraded
Posted: Mon Jun 22, 2009 8:08 pm
by trather
I have upgraded to PB 4.31 and I still can't sort this structure. There are only about 330 item used at this time but the size may grow to about 800 in the end. So I have 1000 set as the limit for right now.
Posted: Mon Jun 22, 2009 8:36 pm
by djes
I don't see what is the point. Maybe the size of the array, but we can't be sure without a code. Here's a functional sample, showing a partially filled array, and displaying datas after sort:
Code: Select all
Structure EmailData
FullName.s
Eid.s
Size.s
E_Server.s
Marsha.s
Domain.s
Dept.s
EndStructure
Global Dim Exchange.EmailData(9)
;Loop to load the data in
For counter=0 To 5
Exchange(Counter)\FullName = Chr(65+Random(26))
; Exchange(Counter)\FullName = Name$
Exchange(Counter)\Eid = EID$
Exchange(Counter)\Size = StrF(MG_Size,2)
Exchange(Counter)\E_Server = Server$
Exchange(Counter)\Marsha = Marsh$
Exchange(Counter)\Domain = Domain$
Exchange(Counter)\Dept = Department$
Debug Exchange(Counter)\FullName
Next counter
SortStructuredArray(Exchange(), #PB_Sort_Ascending, OffsetOf(EmailData\FullName), #PB_Sort_String)
For counter=0 To 9
Debug Exchange(Counter)\FullName
Next counter
Re: Upgraded
Posted: Mon Jun 22, 2009 10:15 pm
by Psychophanta
trather wrote:I have upgraded to PB 4.31 and I still can't sort this structure. There are only about 330 item used at this time but the size may grow to about 800 in the end. So I have 1000 set as the limit for right now.
Put a sample showing your problem.
Full Code
Posted: Tue Jun 23, 2009 6:08 pm
by trather
Here is the full list of code with the procedures.
Code: Select all
Global Counter.l
Structure EmailData
FullName.s
Eid.s
Size.s
E_Server.s
Marsha.s
Domain.s
Dept.s
EndStructure
Global Dim Exchange.EmailData(1000)
Procedure Get_Data(MailBoxFile.s)
Master_Marsha.s = "XXXX1"
OpenFile(1,MailBoxFile)
Counter=1
Header$=ReadString(1)
Line$ = ReadString(1)
Repeat
LastName$ = StringField(Line$, 1, ",")
Last_Name$ = Right(LastName$,Len(LastName$)-1) ; remove Quotes at the start of the name
FirstName$ =StringField(Line$, 2, ",")
First_Name$ = Left(FirstName$,Len(FirstName$)-1); remove Quotes at the end of the name
Name$ = Last_Name$+", "+First_Name$ ; Put Name back together with a Common
EID$ =StringField(Line$, 3, ",")
EID$ = Mid(EID$,2,Len(EID$)-2)
Size$=StringField(Line$, 4, ",")
MG_Size.f = ValF(Size$) /1024
Server$=StringField(Line$, 5, ",")
Server$ = Mid(Server$,2,Len(Server$)-2)
Marsh$=StringField(Line$, 6, ",")
Marsh$ = Mid(Marsh$,2,Len(Marsh$)-2)
Domain$=StringField(Line$, 7, ",")
Domain$ = Mid(Domain$,2,Len(Domain$)-2)
Department$=StringField(Line$, 8, ",")
Department$ = Mid(Department$,2,Len(Department$)-2)
If Marsh$ = Master_Marsha
Exchange(Counter)\FullName = Name$
Exchange(Counter)\Eid = EID$
Exchange(Counter)\Size = StrF(MG_Size,2)
Exchange(Counter)\E_Server = Server$
Exchange(Counter)\Marsha = Marsh$
Exchange(Counter)\Domain = Domain$
Exchange(Counter)\Dept = Department$
Counter +1
EndIf
Line$ = ReadString(1)
Until Eof(1) = 1
CloseFile(1)
EndProcedure
Procedure Write_Data(Mailout.s)
Sp$=Chr(34)+","+Chr(34)
Header$ = Chr(34)+"Display Name"+Sp$+"EID"+Sp$+"Mailbox Size Megs"+Sp$+"Server"+Sp$+"Department"+Sp$
Header$ + "Limit"+Sp$+"Cost"+Chr(34)
OpenFile(2,Mailout)
WriteStringN(2,Header$)
For loop = 1 To Counter -1
H_Nm$ = Exchange(loop)\FullName
H_Eid$ = Exchange(loop)\Eid
H_SZ$ = Exchange(loop)\Size
H_Srv$ = Exchange(loop)\E_Server
H_Mar$ = Exchange(loop)\Marsha
H_Dom$ = Exchange(loop)\Domain
H_DP$ = Exchange(loop)\Dept
Tmp.f = ValF(H_SZ$)
If Tmp > 100.5
Limit$="OVER"
TotalOver.f = (Tmp-100)*0.024
Cost$ = StrF(TotalOver,2)
GrandTotal.f +TotalOver
Else
Limit$="------"
Cost$ =""
EndIf
StringLine$ = Chr(34)+H_Nm$+Sp$+H_Eid$+Sp$+H_SZ$+Sp$+H_Srv$+Sp$+H_DP$+Sp$
StringLine$ + Limit$+Sp$+Cost$+Chr(34)
WriteStringN(2,StringLine$)
Next
WriteStringN(2,"")
WriteStringN(2,Chr(34)+Sp$+Sp$+Sp$+Sp$+Sp$+"Overage Total"+Sp$+StrF(GrandTotal,2)+Chr(34))
CloseFile(2)
EndProcedure
Get_Data("c:\test\test.csv") ; Read the data from file This works fine
SortStructuredArray(Exchange(),#PB_Sort_Ascending, OffsetOf(EmailData\FullName), #PB_Sort_String)
Write_Data("c:\test\new.csv") ; Write the data from the array to a new file This also works as long as I don't sort the array.
MessageRequester("Completed","Check the Drive")
The Get _Data and the Write_Data both work fine as long as I don't sort the array. So I fuess that I am loading the data into the structured array in a format that Sort doesn't like.
Here is the header line and an example of the data that I am reading in.
"DisplayName","EID","MailboxSizeKB","Server","Marsha","Domain","department"
"Smith, Bob","SmithB007",101975,"HOTELEXCH1","XXXX1","ds","12/AAA.00"
Thank you.
Posted: Tue Jun 23, 2009 7:36 pm
by djes
Really easy! Your array is full of void, so after the sort, the datas are at the end... Try to change your line
to
and you'll see the result

(1000, as your array is 1001 elements, change your dim to 999 to have 1000 elements; I know it's a bit strange but it's an old BASIC behaviour)
Posted: Tue Jun 23, 2009 7:49 pm
by Demivec
@trather: You are misusing the array's index to write the data with. This was mentioned earlier by netmaestro.
netmaestro wrote:You'll need to remove any empty array elements. If your array wasn't full all the first entries will be blank and it'll look like your data was destroyed. You can also employ the optional start/end parameters if you know how many entries were read in. Possibly do a redim, etc.
You're doing this:
Code: Select all
After array is constructed it looks like this, counter = 2
index data
----- ------
0 empty
1 info
2 empty
. empty
. empty
1000 empty
After array is sorted it looks like this, counter = 2
index data
----- ------
0 empty
1 empty
2 empty
. empty
. empty
1000 info
When you are writing the arrays contents to disk you are looping from 1 to (counter - 1), which means you won't see the data at index 1000.
You can also simply sort the entries you read like so using the optional Start and Stop parameters in the sort. You would sort then indexes 1 to (counter-1). Sorthing this way will keep them at the indexes from 1 to (counter - 1) so they will be written out properly.
Use this to sort them properly:
Code: Select all
SortStructuredArray(Exchange(),#PB_Sort_Ascending, OffsetOf(EmailData\FullName), #PB_Sort_String,1,Counter - 1)
Thank You all
Posted: Tue Jun 23, 2009 10:19 pm
by trather
Thank you.
I got it. I changed the loop to go from 1 to 1000 and then I put in a an if statment that if the name$ was blank to no write it to the file. I thought that the empty would be at the end of the file but they are null so they are at the top of the array.
That is why even when I nulled the array elements at first I got the same results.
I was just missing that part.
Thank you all again.
Re: Thank You all
Posted: Tue Jun 23, 2009 10:23 pm
by Kaeru Gaman
trather wrote:I changed the loop to go from 1 to 1000 ...
still wrong. first element is always index 0.
in Purebasic, you Dim with the last index, not with the number of elements.
when you Dim var(1000), you have 1001 elements, from 0 to 1000.
Posted: Wed Jun 24, 2009 10:35 pm
by djes
Demivec> Very nice explanation!
Posted: Thu Jun 25, 2009 12:12 am
by Demivec
djes wrote:Demivec> Very nice explanation!
Thanks.