From: Grant on
I have a simple problem related to my inexperiance again. I have a
simple browser and I want to add another column with the fields
calculated from the 2 preceeding fields. I used VirtualFieldColumn to
create the new column but I'm stuck calculating the values for it.
The following is the code so far.
Thank you for any help.

oColumn := oDCbBrowser1:GetOpenColumn(1)
oColumn:Caption := "WEIGHT"
oColumn:Width := 100
oColumn:DataView := bViewStyle{Color{COLORBLACK},
Brush{Color{COLORCYAN}},,oFont}
oColumn:DataView:AlphaBlendRatio := BABR_NONE

oColumn := oDCbBrowser1:GetOpenColumn(2)
oColumn:Caption := "TONNE"+CRLF+"RATE"
oColumn:Width := 100
oColumn:DataView := bViewStyle{Color{COLORBLACK},
Brush{Color{COLORGREEN}}, ,oFont}
oColumn:DataView:AlphaBlendRatio := BABR_NONE


oColumn := bVirtualFieldColumn{self:oDCbBrowser1, odbsServer, {|
oServer|0}, #Expression}
oColumn:Caption := "TOTAL"
oColumn:Width := 100
oColumn:DataView := bViewStyle{Color{COLORBLACK},
Brush{Color{COLORGREEN}},,oFont}
oColumn:DataView:AlphaBlendRatio := BABR_NONE
self:oDCbBrowser1:OpenColumn(oColumn)
From: Stephen Quinn on
Grant

>I have a simple problem related to my inexperiance again. I have a
> simple browser and I want to add another column with the fields
> calculated from the 2 preceeding fields.
There's no guarantee that those columns will have values BEFORE your calc is
called.
Simpler to read the data from the fields themselves.

Something like below should work
- check the syntax though as I typed this from what I have left of my
programming memory<g>

METHOD TotalEmUp( oServer ) CLASS oWin

RETURN oServer:fieldget( #WEIGHT ) * oServer:fieldget( #RATE )

oColumn := bVirtualFieldColumn{self:oDCbBrowser1, odbsServer, l
{|oServer, oWin| oWin:TotalEmUp(oServer) }, #Expression,
SELF}

CYA
Steve



From: Geoff Schaller on
Grant,

You are mixing some concepts here and this may be contributing to your
issues. Firstly, a virtual column is a real column in the browser but
the browser maintains memory of the values you assign the column.
Typically this would be like a check box column where you tick rows you
want to do something with. But it can also be string or numeric to
capture data not held in your data table than you wish to now process
with.

Secondly, an expression column has no persistent value. The value in the
cell displays in the column dynamically as a result of the expression.
This value is not stored anywhere.

So you would never make a virtual column based on an expression because
there is no way to edit/manage the data. It would always change an never
persist.

You need to populate your virtual column with data (and this is usually
human input) or you just have an expression column.

Secondly, try not to use GetOpenColumn(1). Use the symbol name of the
column instead: GetColumn(#myfield). You see a user (or code) can move
columns around and so the column in position 2 may become something
else.

HTH

Geoff


"Grant" <grantd(a)dunsmoreinfo.com> wrote in message
news:2e72846e-c9eb-4dd8-ba69-bf6ecfc42264(a)s13g2000prc.googlegroups.com:

> I have a simple problem related to my inexperiance again. I have a
> simple browser and I want to add another column with the fields
> calculated from the 2 preceeding fields. I used VirtualFieldColumn to
> create the new column but I'm stuck calculating the values for it.
> The following is the code so far.
> Thank you for any help.
>
> oColumn := oDCbBrowser1:GetOpenColumn(1)
> oColumn:Caption := "WEIGHT"
> oColumn:Width := 100
> oColumn:DataView := bViewStyle{Color{COLORBLACK},
> Brush{Color{COLORCYAN}},,oFont}
> oColumn:DataView:AlphaBlendRatio := BABR_NONE
>
> oColumn := oDCbBrowser1:GetOpenColumn(2)
> oColumn:Caption := "TONNE"+CRLF+"RATE"
> oColumn:Width := 100
> oColumn:DataView := bViewStyle{Color{COLORBLACK},
> Brush{Color{COLORGREEN}}, ,oFont}
> oColumn:DataView:AlphaBlendRatio := BABR_NONE
>
>
> oColumn := bVirtualFieldColumn{self:oDCbBrowser1, odbsServer, {|
> oServer|0}, #Expression}
> oColumn:Caption := "TOTAL"
> oColumn:Width := 100
> oColumn:DataView := bViewStyle{Color{COLORBLACK},
> Brush{Color{COLORGREEN}},,oFont}
> oColumn:DataView:AlphaBlendRatio := BABR_NONE
> self:oDCbBrowser1:OpenColumn(oColumn)

From: Kevin on
Grant,

Try setting up your virtual column like this:
bVirtualFieldColumn{ oBrw, oServer, {| oServer | oServer:Weight *
oServer:Tonne}, #Expression}

I use this sort of thing in one of my apps. Obviously change the
calculation needed. If you need a more complex calculation see Stephen's
reply.

Hope this helps.

Kevin


"Grant" <grantd(a)dunsmoreinfo.com> wrote in message
news:2e72846e-c9eb-4dd8-ba69-bf6ecfc42264(a)s13g2000prc.googlegroups.com:

> I have a simple problem related to my inexperiance again. I have a
> simple browser and I want to add another column with the fields
> calculated from the 2 preceeding fields. I used VirtualFieldColumn to
> create the new column but I'm stuck calculating the values for it.
> The following is the code so far.
> Thank you for any help.
>
> oColumn := oDCbBrowser1:GetOpenColumn(1)
> oColumn:Caption := "WEIGHT"
> oColumn:Width := 100
> oColumn:DataView := bViewStyle{Color{COLORBLACK},
> Brush{Color{COLORCYAN}},,oFont}
> oColumn:DataView:AlphaBlendRatio := BABR_NONE
>
> oColumn := oDCbBrowser1:GetOpenColumn(2)
> oColumn:Caption := "TONNE"+CRLF+"RATE"
> oColumn:Width := 100
> oColumn:DataView := bViewStyle{Color{COLORBLACK},
> Brush{Color{COLORGREEN}}, ,oFont}
> oColumn:DataView:AlphaBlendRatio := BABR_NONE
>
>
> oColumn := bVirtualFieldColumn{self:oDCbBrowser1, odbsServer, {|
> oServer|0}, #Expression}
> oColumn:Caption := "TOTAL"
> oColumn:Width := 100
> oColumn:DataView := bViewStyle{Color{COLORBLACK},
> Brush{Color{COLORGREEN}},,oFont}
> oColumn:DataView:AlphaBlendRatio := BABR_NONE
> self:oDCbBrowser1:OpenColumn(oColumn)

From: richard.townsendrose on
Grant,

actually it is not as simple as that ...

a) you MUST make sure that the columns cannot be moved. This is
because bbrowser works firstly row by row going downwards, and within
each row starting with the left columns and working to the right.

b) secondly I have found that this works:
create the columns like this:
oCol:=bDataColumn{SELF:oDCbrGroups,SELF:oAD,{|oSvr, oWin, cItem|
oWin:GetInfo(oSvr:FIELDGET(#ASSETREF), cItem)}, #Expression, SELF,
cItem}

The GetInfo method calls the StoreInfo method and here is my code. You
will have to simplify the GetInfo as we have a very complex situation.
But the basic idea is as follows:

GetInfo reads the data you need column by column and does the
calculation which requires knowledge of the previous column but that
wont be displayed by bbrowser till it gets to the last column, so you
need StoreInfo

METHOD GetInfo(cGroup, cItem) CLASS WFReview
LOCAL cAns:='' AS STRING
LOCAL cAns2:='' AS STRING
LOCAL cDocType AS STRING
LOCAL lLast AS LOGIC
LOCAL cTypeRef AS STRING
LOCAL cKeyWord AS STRING
LOCAL cKeyType AS STRING
LOCAL cColType AS STRING
LOCAL cSrc AS STRING
LOCAL cForm AS STRING
LOCAL cTrigCol AS STRING
LOCAL cTrigType AS STRING
LOCAL lReqd:=TRUE AS LOGIC
LOCAL cDocNo:='' AS STRING
LOCAL lDirExists AS LOGIC

IF SELF:baPF:Locate({|oSvr|oSvr:FIELDGET(#ITEMNO) == cItem})

cDocType:=SELF:baPF:FIELDGET(#DOCTYPE)
lLast:= SELF:baPF:FIELDGET(#FIRST) // index in reverse date
order
cTypeRef:=SELF:baPF:FIELDGET(#TYPEREF)
cKeyWord:=Upper(AllTrim(SELF:baPF:FIELDGET(#KEYWORD)))
cKeyType:=SELF:baPF:FIELDGET(#KEYTYPE)
cSrc:=SELF:baPF:FIELDGET(#IOCODE)
cForm:=SELF:baPF:FIELDGET(#CONTTYPE)
cColType:=SELF:baPF:FIELDGET(#DataShow)
cTrigCol:=SELF:baPF:FIELDGET(#TrigCol)
cTrigType:=SELF:baPF:FIELDGET(#TrigType)

// is it triggered
IF ! Empty(cTrigCol)
cAns2:=Upper(SELF:StoreInfo(cGroup, cTrigCol, '', TRUE)) //
recall data
DO CASE
CASE Instr('ERROR', cAns2) .OR. Instr('NOT FOUND', cAns2)
lReqd:=FALSE
CASE cTrigType == TRIG_TYPE_YES
IF ! Instr(Upper(cAns2), 'YES Y')
lReqd:=FALSE
ENDIF
CASE cTrigType == TRIG_TYPE_NO
IF ! Instr(Upper(cAns2), 'NO N')
lReqd:=FALSE
ENDIF
CASE cTrigType == TRIG_TYPE_EMPTY
IF ! Empty(cAns2)
lReqd := FALSE
ENDIF
CASE cTrigType == TRIG_TYPE_FULL
IF Empty(cAns2)
lReqd := FALSE
ENDIF
ENDCASE
ENDIF

DO CASE
CASE ! lReqd
cAns:=''

CASE cDocType == DOC_TYPE_NAME // print a field
from docnm
IF Instr(cKeyWord, '#TYP1 #TYP2 #POSTCODE #CONTACT')
IF cKeyWord == '#POSTCODE'
cAns:=LookupName(cGroup, #POSTCODE)
ELSEIF cKeyWord == '#TYP1'
cAns:=LookupCategory(NAME_POSITION, LookupName(cGroup, #TYP1))
ELSEIF cKeyWord == '#TYP2'
cAns:=LookupCategory(NAME_TYPE, LookupName(cGroup, #TYP2))
ELSEIF cKeyWord == '#GROUPATTS'
lDirExists:=DirExists(SysObject():GetParam(PathGpAtts) +
AllTrim(SELF:cJobNo)+'\'+AllTrim(cGroup))
IF lDirExists
cAns:=NTrim(ALen(Directory(SysObject():GetParam(PathGpAtts) +
AllTrim(SELF:cJobNo)+'\'+AllTrim(cGroup)+'\*.*')))
ELSE
cAns:='NO'
ENDIF
ELSEIF cKeyWord == '#CONTACT' // added 200110
cAns:=LookupNameC(cGroup)
ENDIF
ELSE
cAns:='Error - List'
ENDIF

CASE cDocType == DOC_TYPE_CONTACT
// locate contact - jobno+assetref+subjref+nameref
+str(descend(DATED))
IF SELF:oCU:Seek(SELF:cJobNo + cGroup + cTypeRef + cGroup, FALSE,
lLast)
IF cColType == COL_TYPE_DOCFIELD .AND. ! Empty(cKeyWord)
IF Instr(cKeyWord,'NAMEREF MADEBY DATED NEXTDATE')
cAns:=AsString(SELF:oCU:FIELDGET(cKeyWord))
ELSEIF Instr(cKeyWord,'CONTTYP1 REASON CONTSTATUS NEXTTYP1')
IF Instr(cKeyWord, 'CONTTYP1 NEXTTYP1')
cAns:=LookupCategory(CONTACT_MODE,
AsString(SELF:oCU:FIELDGET(cKeyWord)))
ELSEIF cKeyWord == 'REASON'
cAns:=LookupCategory(CONTACT_REASON,
SELF:oCU:FIELDGET(#REASON))
ELSEIF cKeyWord == 'CONTSTATUS'
cAns:=LookupCategory(CONTACT_STATUS,
SELF:oCU:FIELDGET(#CONTSTATUS))
ENDIF
ELSE
cAns:='Field Error'
ENDIF
ELSEIF cColType == COL_TYPE_KEYWORD .AND. ! Empty(cKeyWord)
cAns:=GetKeyData(cKeyWord, SELF:oCU:FIELDGET(#TEXTREF),
cKeyType, FALSE)
IF cKeyType == KEY_TYPE_YES_NO .AND. Instr('Y',
Upper(cAns))
cAns:=cAns
ELSEIF cKeyType == KEY_TYPE_YES_NO .AND. Instr('N',
Upper(cAns))
cAns:=cAns
ELSE
cAns:=cAns
ENDIF
ELSEIF cColType == COL_TYPE_EXIST
cAns:='Exists'
ELSE
cAns:='Error - Contact'
ENDIF
ELSE
cAns:='Not found'
ENDIF

CASE cDocType == DOC_TYPE_MAIL // gendoc
// locate document - Jobno+AssetRef+SubjRef+DocSrc+Type
+str(descend(DATERECVD))
IF SELF:oGD:Seek(SELF:cJobNo + cGroup + cTypeRef + cSrc + cForm,
FALSE, lLast)
IF cColType == COL_TYPE_DOCFIELD .AND. ! Empty(cKeyWord)
IF Instr(cKeyWord,'DATERECVD DATEMADE DOCTITLE GOTFROM SENDERREF
SENTTO BYWHOM')
cAns:=AsString(SELF:oGD:FIELDGET(cKeyWord))
ELSEIF Instr(cKeyWord,'DOCSENT')
cAns:=IIF(SELF:oGD:FIELDGET(#DOCSENT), 'Sent', 'Available')
ELSEIF Instr(cKeyWord,'MODERECD') // rgtr 270410
cAns:=SayMode(SELF:oGD:FIELDGET(#MODERECD))
ELSE
cAns:='Field Error'
ENDIF
ELSEIF cColType == COL_TYPE_KEYWORD .AND. ! Empty(cKeyWord)
cAns:=GetKeyData(cKeyWord,
RtfToText(SELF:oGD:FIELDGET(#MESSTEXT)), cKeyType, FALSE)
IF cKeyType == KEY_TYPE_YES_NO .AND. Instr('Y',
Upper(cAns))
cAns:=cAns
ELSEIF cKeyType == KEY_TYPE_YES_NO .AND. Instr('N',
Upper(cAns))
cAns:=cAns
ELSE
cAns:=cAns
ENDIF
ELSEIF cColType == COL_TYPE_EXIST
IF SELF:oGD:FIELDGET(#DOCSENT)
cAns:='Sent'
ELSE
cAns:='Available'
ENDIF
ELSE
cAns:='Error - Mail'
ENDIF

ELSE
cAns:='Not found'
ENDIF

CASE cDocType == DOC_TYPE_FWD_MAIL// Lower(FORM_TYPE) // forward
gendoc
// locate document - Jobno+AssetRef+SubjRef+DocSrc+Type
+str(descend(DATERECVD))
IF SELF:oGD:Seek(SELF:cJobNo + cGroup + cTypeRef + cSrc + cForm,
FALSE, lLast)
cDocNo:=SELF:oGD:FIELDGET(#DOCNO)
// locate if sent JobNo+DocSrc+Type+DocNo+NameRef
IF SELF:oCP:Seek(SELF:cJobNo + cSrc + cForm + cDocNo)

cAns:='Available'
SELF:oCP:OrderScope(TOPSCOPE, SELF:cJobNo + cSrc +
cForm + cDocNo)
SELF:oCP:OrderScope(BOTTOMSCOPE, SELF:cJobNo +
cSrc + cForm + cDocNo)
SELF:oCP:GoTop()
DO WHILE ! SELF:oCP:EoF
IF SELF:oCP:FIELDGET(#WHATTODO) == cKeyType
cAns:='Sent'
IF !
Empty(SELF:oCP:FIELDGET(#ACTIONDATE))

cAns:=DToC(SELF:oCP:FIELDGET(#ACTIONDATE))
EXIT
ENDIF
ENDIF
SELF:oCP:Skip()
ENDDO

ELSE
cAns:='Available'
ENDIF

ELSE
cAns:='Not found'
ENDIF

OTHERWISE
cAns:='See RGTR !'

ENDCASE

ELSE /// ooooooouuuuuucccccccchhhhhhhh
cAns:='Lost:'+ AllTrim(cGroup) +':'+cItem
ENDIF

SELF:StoreInfo(cGroup, cItem, cAns, FALSE) // store
info

RETURN AllTrim(cAns)
METHOD StoreInfo(cGroup, cItem, cInfo, lRecall) CLASS WFReview
STATIC LOCAL cHeldGroup AS STRING
STATIC LOCAL aData:={} AS ARRAY // {item,info}
LOCAL cAns:='' AS STRING
LOCAL n AS DWORD

IF Empty(cHeldGroup)
cHeldGroup:=cGroup
aData:={}
ELSEIF ! cGroup == cHeldGroup
cHeldGroup:=cGroup
aData:={}
ENDIF

IF lRecall
n:=AScan(aData,{|a|Upper(a[1]) == Upper(cItem)})
IF n > 0
cAns:=aData[n,2]
ELSE
cAns:='Problem'
ENDIF
ELSE
AAdd(aData,{cItem, cInfo})
ENDIF

RETURN cAns

regards

richard