Resolved Building and populating dynamic temp-table.

bigwill

Member
Hi all.
I need some help.

I will try to explain my problem. I am building up a dynamic temp-table and populating it from a query before i export this temp-table as xml over to my .NET application. Building the temp-table is ok, but upon filling it with data i have come across a problem. On a couple of fields i have to check in another table to get the field-name i have used. if i write hb::"nameOfField" there is no problem, but if i lookup this field-name in a table i get an error. This do not work : bh: "tt.column".

I have attached a samle code which displays my problem.
Code:
def temp-table bb no-undo
  field field-name as char.
create bb.
assign bb.field-name = "NewFieldName".

def var cFields as char init "col1,col2" no-undo.
def var cFieldsDataType as char init "character,character" no-undo.

def var i as int no-undo.

DEFINE VARIABLE htt  AS HANDLE      NO-UNDO.
DEFINE VARIABLE hb  AS HANDLE      NO-UNDO.

/*create temp-table dynamically*/
CREATE TEMP-TABLE htt.
do i = 1 to num-entries(cFields,','):
  htt:ADD-NEW-FIELD(entry(i,cFields,','), entry(i,cFieldsDataType,',')).
end.
find first bb no-lock no-error.
if avail bb then
  htt:ADD-NEW-FIELD(bb.field-name, 'character').

htt:temp-table-prepare("tt":U).
hb = htt:DEFAULT-BUFFER-HANDLE.

hb:BUFFER-CREATE().

if lookup("col1",cFields) > 0 then
  hb::col1 = "myfirstfield".

if lookup("col2",cFields) > 0 then
  hb::col2 = "Secondfield".

/*Everyting ok until here*/
find first bb no-lock no-error.
/*The following line works ok*/
if avail bb then
  hb::NewFieldName = "yoohoo".

/*I don't know the name and therefor i have to use the value from bb*/
/*this don't work. This is my problem*/
if avail bb then
  hb::bb.field-name = "yoohoo".


def var a as logical no-undo.
def var c as longchar no-undo view-as editor large inner-chars 200 inner-lines 50.
a = htt:default-buffer-handle:write-xml("longchar",c,true,?,?,true,false).
display c with width 280.

Anyone with some tips. I have tried:
if avail bb then
bb::value(bb.field-name) and
if avail bb then
bb::string(bb.field-name) with no luck
 

bigwill

Member
No this don't help.
I get following error:
"BUFFER-FIELD buffer-field was not found in buffer tt."
and then "Lead attributes in a chained-attribute expression (a:b:c) must be type HANDLE or a user-defined type and valid (not UNKNOWN). (10068)"

Try to run this example:
Code:
/*temp-table with one record. This record is added to another temp-table as column*/
def temp-table bb no-undo
  field field-name as char
  field field-value as char.
create bb.
assign bb.field-name = "NewFieldName"
      bb.field-value = "SomeValue".
 
def var cFields as char init "col1,col2" no-undo.
def var cFieldsDataType as char init "character,character" no-undo.
def var i as int no-undo.
def var htt as handle no-undo.
def var hb as handle no-undo.
 
/*create temp-table dynamically*/
create temp-table htt.
do i = 1 to num-entries(cFields,','):
  htt:ADD-NEW-FIELD(entry(i,cFields,','), entry(i,cFieldsDataType,',')).
end.
 
/*Add the record from bb as a column in htt as char*/
find first bb no-lock no-error.
if avail bb then
  htt:ADD-NEW-FIELD(bb.field-name, 'character').
 
htt:temp-table-prepare("tt").
hb = htt:default-buffer-handle.
 
/* populate temp-table */
hb:BUFFER-CREATE().
 
if lookup("col1",cFields) > 0 then
  hb::col1 = "myfirstfield".
 
if lookup("col2",cFields) > 0 then
  hb::col2 = "Secondfield".
 
/* Now the problem starts. I have to lookup in temp-table bb
  and add the field value to temp-table htt 
  This works (but in real life i do not know the fieldname, so i
  must match fieldname from temp-table bb with fieldname in htt..
  if avail bb then
    assign hb::NewFieldName = "SomeValue".  */
 
 
/*This don't work. This is my problem*/
find first bb no-lock no-error.
if avail bb then
  hb::buffer-field(bb.field-name):buffer-value = "yoohoo".
 
/* Display temp-table as xml for debug only */
def var a as logical no-undo.
def var c as longchar no-undo view-as editor large inner-chars 200 inner-lines 50.
a = htt:default-buffer-handle:write-xml("longchar",c,true,?,?,true,false).
display c with width 280.
 

RealHeavyDude

Well-Known Member
Obviously you have an issue with the scope of the default buffer that comes with your Temp-Table bb. It's the whole procedure, therefore the record got created but it's field modificatons are written back at the end of the buffer scope. In you case this happens after your logic to populate the dynamic temp-table fires.

That's a classic example of Temp-Table buffer scoping. You need to define a buffer for your Temp-Table bb and do something like this:
Code:
define buffer b_bb for bb.
 
do for b_bb: /* Strong scope */
  create b_bb.
  assign b_bb. ....
end.

I generally recommend the usage of defined buffers and strong scoping when updating Temp-Tables.

Heavy Regards, RealHeavyDude.
 

bigwill

Member
I thing i got it.

I had:
hb::buffer-field(bb.field-name):buffer-value = "yoohoo".
just removed the one ":" to
hb:buffer-field(bb.field-name):buffer-value = "yoohoo".

It works :)

One more question. Are these 2 example the same:
hb::Field1 = "SomeValue" or
hb:buffer-field("Field1"):buffer-value = "SomeValue" ?
 
Top