FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour macro substitution & in fieldnames
Posts: 1487
Joined: Tue Jun 14, 2016 07:51 AM
macro substitution & in fieldnames
Posted: Tue Oct 25, 2016 09:16 PM
It is a piece of code for a mapping system

I have 3 databases

dbf1 -> with just 1 record filled with fieldnames of dbf 2
ID : "STYLE"
NAME : "TITLE"
CATMAIN : "CAT1"
...

dbf2 -> actual datafile (source data)
STYLE : "200444"
TITLE : "Safetyshoes dassy"
CAT1 : "Safetyshoes"
....

dbf3 -> target datafile where i what to put the data from dbf2
ID : "CUST->STYLE" -> should be "200444"
NAME : "CUST->TITLE" -> should be 'Safetyshoes dassy"
CATMAIN : "CUST->CAT1" ->should be 'Safetyshoes"

So, I do something wrong with the & operator

Here I miss the logic of converting strings
Code (fw): Select all Collapse
             if apos > 0  // if >0, it is a fieldname else a standard data like "21%"
                cTarget = "slave->"+fieldname(i)

  //            cField = "CUST->"+aCustfields[i]
                cField = "CUST->"+cLookup

 //               cData = &cField // not working
                cData = cField

              &cTarget = cData
            else  // standard data, but no fieldname
                cData = cField  
                &cTarget = cData
           endif



Full Function

Code (fw): Select all Collapse
function filldbf()
   Local aCustfields:={}

   use slave
   select slave
   zap
   close
   use DASSY NEW alias CUST
   use slave NEW alias slave
   use master NEW alias master

   select cust
   for i = 1 to cust->(FCOUNT())
      AADD(aCustfields,Fieldname(i))  // make arry with all fieldnames from datafile
   next

   select master
   master->(dbgotop())
   nMasterfields = master->(fcount())
   cust->(dbgotop())
   nTel = 0

   do while !cust->(eof())
      slave->(dbappend())

      for i = 1 to nMasterfields

         cWelkField = "master->"+fieldname(i)
         clookup = alltrim(&cWelkfield)        // data from the masterfile, result = fieldname to look for next
         if !empty(clookup)
            apos = ascan(aCustfields,clookup)  // to see if the data is a fieldname, could also be simple data

             if apos > 0  // found as a fieldname
                cTarget = "slave->"+fieldname(i)

  //            cField = "CUST->"+aCustfields[i]
                cField = "CUST->"+cLookup

 //               cData = &cField // not working
                cData = cField

              &cTarget = cData
            else  // standard data, but no fieldname
                cData = cField  // GIVES THE DATA, BUT ERROR FOR THE NEXT DO/ENDDO LOOK
                &cTarget = cData
           endif
         endif
        next
      cust->(dbskip())
   enddo

   select slave
   xbrowse()
   close all
return


The result is a database filled with the fieldnames, but not the fielddata

Marc Venken

Using: FWH 23.08 with Harbour
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: macro substitution & in fieldnames
Posted: Wed Oct 26, 2016 12:13 AM
Look, I hope it's what you need

Code (fw): Select all Collapse
#include "Fivewin.ch"

MEMVAR cAlias

//----------------------------------------------------------------------------//

Function Main()

   //local cAlias
   local cField
   local uVal
   
Use "Customer.dbf" ALIAS custom
   
   cAlias := Alias()
   
   cField := ( cAlias )->( FieldName( 1 ) )
   ? ( cAlias )->( FieldName( 1 ) ), ( cAlias )->( FieldGet( 1 ) )
   uVal := ( cAlias )->First
   ? uVal, cField
   cField := "( cAlias )->"+cField
   ? &(cField)
   &(cField)  := "Field modified"
   //   &(cField)  := "Homer"
   ? ( cAlias )->( FieldGet( 1 ) )

Return nil
Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo

El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 1598
Joined: Fri Oct 07, 2005 05:56 PM
Re: macro substitution & in fieldnames
Posted: Wed Oct 26, 2016 07:57 AM
Dear Marc,

I use as you did but a bit different.
Code (fw): Select all Collapse
RvName := 'MHS->MHS_RV'+right(dtos(MEMVAR->comdat),2)
&(RvName) += round(TRN->TRN_UNIT * TRN->TRN_QTTY,2)
Regards,

Dutch



FWH 2304 / xHarbour Simplex 1.2.3 / BCC73 / Pelles C / UEStudio

FWPPC 10.02 / Harbour for PPC (FTDN)

ADS V.9 / MySql / MariaDB

R&R 12 Infinity / Crystal Report XI R2

(Thailand)
Posts: 1515
Joined: Thu Oct 30, 2008 02:37 PM
Re: macro substitution & in fieldnames
Posted: Wed Oct 26, 2016 08:42 AM
Macro substitution is bad:
- slow (more slow than dbf field functions)
- avoid compiler syntax analisys.


Better harbour programming style is do not use macro substitution, so:

Code (fw): Select all Collapse
// With preprocessor  is more rapid and clear with pseudo functions:
#Define FPOS_(aTarget) ;
            (aTarget[1])-> ( FieldPos(aTarget[2]) )
#Define FPUT(aTarget, xValue) ;
            (aTarget[1])-> ( FieldPut( FPOS_(aTarget), xValue) )
#Define FGET_(aTarget) ;
            (aTarget[1])-> ( FieldGet( FPOS_(aTarget), xValue) )

// Sample:
aTarget:= {"slave", fieldname(1)}

FPUT_(aTarget, "hi !")
xVar:= FGET_(aTarget)
nPos:= FPOS_(aTarget)


Regards
Posts: 24
Joined: Thu Oct 02, 2014 03:51 AM
Re: macro substitution & in fieldnames
Posted: Wed Oct 26, 2016 03:19 PM
Marc:

Look at this examples code:

PADRON->(DBGOTOP())
DO WHILE !PADRON->(EOF())

IF !TMOVMES->(DBSEEK(CONCEPTO->COD+PADRON->MP,.F.))

TPADRON->(DBAPPEND())
COPIAREG('TPADRON','PADRON')

ENDIF

PADRON->(DBSKIP())
ENDDO

FUNCTION COPIAREG(xBaseEntra,xBaseSale)

Local aCampos:={},i,aDatos:={},aCampos2,aAt

aCampos:=(xBaseEntra)->(dbstruct())
aCampos2:=(xBaseSale)->(dbstruct())

FOR I:=1 TO LEN(aCampos2)
IF ASCAN(aCampos,{|aAt| aAt[1]==aCampos2[i,1]}) >0
(xBaseEntra)->&(aCampos2[i,1]):=( xBaseSale )->&(aCampos2[i,1])
ELSE
* ? 'NO EXISTE EL CAMPO EN ',XBASEENTRA,'I=',I,aCampos2[i,1]
ENDIF
NEXT

return nil


BUS_DES('PADRON',2,MOVMES->MP,'ESPE')

Function BUS_DES(XARCH, XORDEN, XCLAVE, XCAMPO)

Local RET:=SPAC(0) , ORD_ACT, AREA_ACT := SELECT(), cRegis

IF SELECT(XARCH) == 0
USE (WPATH + "\" + XARCH) SHARED NEW
ENDIF

DBSELECTAR(XARCH)
cRegis:=RECNO()
ORD_ACT = INDEXORD()

SET ORDER TO XORDEN

DBSEEK((XCLAVE))
IF FOUND() .AND. !DELETED()
RET = EVAL(FIELDBLOCK(XCAMPO))
ELSE
DBGOBOTTOM()
RET = SPACE(LEN(EVAL(FIELDBLOCK(XCAMPO))))
ENDIF
SET ORDER TO ORD_ACT
DBGOTO(cRegis)
SELECT(AREA_ACT)

RETURN RET


Regards,
Daniel Puente
Posts: 1487
Joined: Tue Jun 14, 2016 07:51 AM
Re: macro substitution & in fieldnames
Posted: Wed Oct 26, 2016 11:37 PM
Thanks guys,

With the samples I get it to work !

hmpaquito wrote:Macro substitution is bad:
- slow (more slow than dbf field functions)
- avoid compiler syntax analisys.

Better harbour programming style is do not use macro substitution:


Out of curiosity, You suggested code from Harbour Style.
I'm just new with the FW programming and my skilss are not ready for it yet,
but I wonder how your working code would look like. Here is the code that works for me now.
Should you have any time, i would be a great learning stuff for me.

Code (fw): Select all Collapse
function filldbf()
   Local aCustfields:={}
   local cField
   local uVal
   local cM_field

   MEMVAR cAlias

   use slave
   select slave
   zap
   close
   use DASSY NEW alias CUST
   use slave NEW alias slave
   use master NEW alias master

   select cust
   AliasCust = alias()
   select slave
   Aliasslave = alias()
   select master
   Aliasmaster = alias()

   select cust
   for i = 1 to cust->(FCOUNT())
      AADD(aCustfields,Fieldname(i))  // make arry with all fieldnames from datafile
   next

   select master
   master->(dbgotop())
   nMasterfields = master->(fcount())

   master->(dbgotop())
   cust->(dbgotop())
   do while !cust->(eof())
      slave->(dbappend())
      for i = 1 to nMasterfields
         cM_Field := alltrim(( Aliasmaster )->(FieldGet(i)))
         if !empty(cM_Field)
             nPos = ascan(aCustfields,cM_Field)  // to see if the data is a fieldname, could also be simple data
             cSlaveField := "slave->"+(aliasslave)->(fieldname(i))
             if nPos > 0  // found as a fieldname
                &(cSlavefield) := cust->(fieldget(nPos))
             else  // standard data, but no fieldname
                &(cSlavefield) := &(AliasMaster)->(fieldget(I))
             endif
         endif
        next
      cust->(dbskip())
   enddo
   select slave
   xbrowse()
   close all
return
Marc Venken

Using: FWH 23.08 with Harbour
Posts: 1515
Joined: Thu Oct 30, 2008 02:37 PM
Re: macro substitution & in fieldnames
Posted: Thu Oct 27, 2016 07:24 AM
Here you are:

Code (fw): Select all Collapse
function filldbf()
   Local aCustfields:={}
   local cField
   local uVal
   local cM_field

   // MEMVAR cAlias

   use slave
   select slave
   zap
   close
   use DASSY NEW alias CUST
   use slave NEW alias slave
   use master NEW alias master

   select cust
   AliasCust = alias()
   select slave
   Aliasslave = alias()
   select master
   Aliasmaster = alias()

   select cust
   for i = 1 to cust->(FCOUNT())
      AADD(aCustfields,Fieldname(i))  // make arry with all fieldnames from datafile
   next

   select master
   master->(dbgotop())
   nMasterfields = master->(fcount())

   master->(dbgotop())
   cust->(dbgotop())
   do while !cust->(eof())
      slave->(dbappend())
      for i = 1 to nMasterfields
         cM_Field := alltrim(( Aliasmaster )->(FieldGet(i)))
         if !empty(cM_Field)
             nPos = ascan(aCustfields,cM_Field)  // to see if the data is a fieldname, could also be simple data
             cSlaveField := "slave->"+(aliasslave)->(fieldname(i))
             if nPos > 0  // found as a fieldname
                // &(cSlavefield) := cust->(fieldget(nPos))
                Slave-> ( FieldPut ( i,  Cust->(FieldGet(nPos)) )  // This and...
             else  // standard data, but no fieldname
                // &(cSlavefield) := &(AliasMaster)->(fieldget(I))
                Slave-> ( FieldPut ( i,  (cAliasMaster)->(FieldGet(i)) )  // ... this 
             endif
         endif
        next
      cust->(dbskip())
   enddo
   select slave
   xbrowse()
   close all
return
Posts: 1487
Joined: Tue Jun 14, 2016 07:51 AM
Re: macro substitution & in fieldnames
Posted: Thu Oct 27, 2016 10:26 PM

Thanks,

It works! and is better for reading the code.

Learning every day..

Thanks.

Marc Venken

Using: FWH 23.08 with Harbour

Continue the discussion