WindowManager.Update calling BrowseClass.UpdateViewRecord - RC = ErrorCode() - Error 78 Invalid Number of Parameters

Any ideas how I can further track down the Error 78 thats being thrown by the Browse Class method UpdateViewRecord which is called by the WindowManager.Update method?

When I look at the parameters in the debugger I dont know what they should be and shouldnt be, so wondered if theres any info on what these parameters should be.

When I look at the Self.S I can see values which appear in the view but these will also be in the key.
What I see is
8,8,0,0,0,2,128,0,0,1,c:\C6 Classes,0,0,0,0, upto the 1000th byte.
The field is a cstring 2048 chars long which considering the 1000char limit in self.s might be causing my problems.

I see in its a String reference ie
StandardBehavior Class, Implements
S &String, Private

Tracking that back, the 1000 char limit is set when the init procedure is called
StandardBehavior.Init Procedure(queue q, *string pos, signed lc)
self.s &= pos

tracking that back the browse class calls it
BrowseClass Class(ViewManager)…
Behavior &StandardBehavior

But I still cant figure out where its getting the 1000 char limit, tracking these thing back is tedious.

Any ideas if you know?


The ABC classes have a set limit for POSITION() that I think is 1024 characters and has been known to cause problems.
A solution is here:

Mine is TPS file so I might be more restricted than an SQL backend. I have been looking at the view position.

Some of the fields in the Parameter group structure are self explanatory, but others not. Funnily enough this is one of those situations where the C4 driver development kit or maybe an earlier version of clarion would be handy for the documentation if not anything else. I know Z said in the recent ClarionLive podcast on youtube, someone asked if that could be made available for developing a postgres driver, and Z said its come up alot so would commit to doing a postgress driver, but he also said its (Database Driver Development Kit) not in a state fit to release without tidying up, which might include documentation.

So at this stage I’d dont know if I’m hitting a TPS limit or not. I’ve already changed some of those values @Mark_Sarson has mentioned, but no joy this end, which is why I said it might be a TPS limit.

Still testing though…

Along time ago I was hitting a limit with the length of the filter statement, because the user selected some options which built a filter statement so I have had to expand the filter statement in the classes before. This was early C6 days.


So here is where things dont make sense.

In the ThisWindow.Init you get the browseclass.inits.

The BrowseClass.Init is where *string Posit is used to make the StandardBehavior S 1000 characters.

In the code its Queue:Browse.ViewPosition which is passed and this is 1024 characters or bytes. So where is the 24 chars disappearing to between the BRWxy.Init(?ListBox,Queue:Browse.ViewPosition,…
and StandardBehavoir.init(Q.Posit)

It doesnt make sense where those 24chars or bytes are disappearing to.

BRowseClass.Init Procedure(Signed ListBox, *String Posit, View V, Queue Q, RelationManager F, WindowManager WM)
Self.Behavior &= New StandarBehavior

*String Posit = Queue:Browse.ViewPosition which is 1024 chars, and there is no value in view position its all chr(32) spaces, yet when you call BRowseClass.Init *string posit becomes 1000bytes.

It seems to be losing the 24 byte spaces when the BrowseClass.Init method is called, which would suggest some sort of runtime restriction.

Oh well, I could modifiy one of the classes to force it to use 1024 bytes or more, but if the runtime is cutting off 24bytes, where else is it cutting of 24 bytes.

This is in C6, mind, havent tested in C11 yet, the runtime in C11 might be fine.

So none of marks suggestions would work because these are all 1024 bytes/chars and the issue I have is tracking down where this 1000 char/byte limit is set.

What I’ve done is searched for 1000 char limits in the templates and classes.

So far tried with no success,
abfile.clw FileManager.AddKey
FB Cstring(1000),auto
as:addrFileManager Equate(1000)

and by trying a smaller number of bytes ie 512, that way I should be able to tell if its the code in question or not.

The only other possibility is the function Position() which might be limited to 1000 chars which I’ve got not control over and the help docs dont say if its return value is limited to 1000chars.

But I am at a total loss as to what is controlling this 1000char limit at this stage.

The thing that just does not make any sense is the procedure method accepting a string passed by address and when that string has a different declared size, its not not reflected in the passed parameter which would suggest some sort of interception is taking place.

Maybe time to look at the assembler and see whats going on there because there isnt anything else in the classes I can change from 1000chars to something else that affects this class. All very Spooky!

Well stepping through the assembler I can see posit is being passed in the EDX register on the stack when the browseclass.init is called, I can see the 1000 chars at the EDX memory address, but cant tell where this is set. I cant see anything in the viewmanager class which is its parent, so I’m still wondering if this is a limit in the Position() function because the help doc suggests the format seen is what can be seen in the class, ABBrowse Standardbehavior class
self.s &= Pos
So this is looking like a TPS file limit which Position() is showing.

Yet the help docs say a TPS Key size can be 15,000 bytes, the only 1000byte restriction seen is the table name.


Well Position() is returning a string which is 2056 chars long when I pass the key with with two fields that total 2056 characters in length, so its back to the classes to find out why Posit in BRowseClass.Init Procedure(Signed ListBox, *String Posit, View V, Queue Q, RelationManager F, WindowManager WM) is a 1000 chars in size.

Solved. The Queue ViewPosition var doesnt work with Position() in all cases.

And my debugger was only showing 1000chars/bytes from the ViewPositions 1024 chars/bytes.

Dont know why the debugger is showing the wrong value, but debugview exists as a backup which shows the correct value.

Here’s the modified template code which works in C6
#Insert(%MakeField, 'ViewPosition', '', 'String(1024)','Entry''s view position')
change to
#Insert(%MakeField, 'ViewPosition', '', 'String(' & %LongestKey() &')','Entry''s view position')

and then add at the bottom of the ABBrowse.tpw file

#Set(%KeyLength,%KeyLength+4)  #!Adds Position()'s 4 bytes + sum of the sizes of the fields in the key
#IF(%KeyLength<1024)  #!If the KeyLength is less than the original ViewPosition var's 1024 chars/bytes, it keeps it that way for compatibility reasons.

This %LongestKey group gets the Queue’s Primary file’s keys and works out which key and its fields totalled is the longest and then makes the viewposition that length if its longer than the current 1024 chars. If its less than 1024 chars, it keeps it that way because I dont know if anyone else is doing stuff to the ViewPosition var.

This should get rid of all the Error 78’s, including the one’s mentioned here What causes an Error 78 and/or sometimes "phantom" records in a browse? but let me know if it doesnt.

Getting the Longest Length from only the Primary file does NOT look like the fix for a Browse.

The Browse uses ViewPosition = POSITION(View) and not just POSITION(Primary). According to the Help on POSITION(View) the Position String includes all Secondary File Keys i.e. Join(, Secondary File Key). So you need to walk the View files and add the length of those keys.

The help hints that the Position is driver specific (aka “underlying file system”) it’s not documented. I wonder if the Position requires both Order By key position fields for sequence … and … primary key fields. Maybe a Trace would show something.

VIEW usage
The return string for POSITION(view) contains all the information required by the underlying file system to reset to the one specific position within the record set currently in the VIEW. It also contains the file system’s POSITION return value for the primary file key and all secondary file linking keys. This allows POSITION(view) to accurately define a position for all related records in the VIEW.

1 Like

That might be the case, but I’ll let someone else sort it out, I’ve had enough of my life being stolen, its time to get payback.

It would be easy to make a temporary change to a Browse column to show the Position() length of View and Primary, or add columns, to quickly understand the possible sizes. Try this with more complex Views that have several Joins.

 BRW1::Ven:Name = 'Pos(View)=' & LEN(POSITION(BRW1::View:Browse)) & |    
                ', Pos(File)=' & LEN(POSITION(Vendors))