Page 2 of 4

Re: Doing Master detail in the best way..

Posted: Mon Jul 26, 2010 1:34 am
by esgici
Hola Charly
cdsaenz wrote:I think I'll have to get back to basics!!
Don't worry, this is usual more than you imagine ;)
cdsaenz wrote:I've figured out something that seems to be working so far: a function that creates the temp file, other that loads the current content (if any) to the temp table and another one that saves back to the real DBF.
Good idea :idea:
cdsaenz wrote:...got back to Grid. Ok but... it seems that the Grid saves the edit in a buffer. So I need to figure out a way to save the buffer to the temp table.. I don't even need that but not sure if I can avoid it. I tried the Save() method of the Grid but it only saves the current record... and there is no even to hook to.. What am I missing?
While testing did you change more than one record ?

I guess that GRID save only changed rows.

Charly, I'm going to sleep.

Sorry if will be late my next post :(

Saludos

--

Esgici

Re: Doing Master detail in the best way..

Posted: Mon Jul 26, 2010 2:53 pm
by cdsaenz
Hi Esgici, yes on the test I did change more than record... If it's just one, no problem, I do Grid.Save before the actual save to the table.. but when it's more than one record... I don't have idea how to save ALL the buffer back to the table.

I tried applying Grid.Save on the Grid.OnChange event, but it would repaint and reposition the Grid, so no way..

Probably the best idea is to have the grid readonly and update rows on a separate form, but it's more work and against my usual method.. For using the grid I'd like a couple of things that I don't know if are possible:

- Field level validation
- Lookup fields (ex: show description of account, I can handle with field level validation)
- Autoedit: using enter to go from cell to cell, and go to the next record after the rightmost cell is edited.

I'll see what I do! I just want to know my possibilities. Thanks!! :)

Re: Doing Master detail in the best way..

Posted: Mon Jul 26, 2010 3:04 pm
by esgici
Hi Charly
cdsaenz wrote:Hi Esgici, yes on the test I did change more than record... If it's just one, no problem, I do Grid.Save before the actual save to the table.. but when it's more than one record... I don't have idea how to save ALL the buffer back to the table.

I tried applying Grid.Save on the Grid.OnChange event, but it would repaint and reposition the Grid, so no way..
This is bad news, before passed this handicap we can't advance :(

Could you please send me this "wrong working" sample; as soon as possible simple, short and working please.

And a little piece of your data of course.

If you prefer use my private e-mail address : esgici @ gmail . com

Saludos

--

Esgici

Re: Doing Master detail in the best way..

Posted: Mon Jul 26, 2010 5:54 pm
by esgici
Hi Charly

Please take a look ..\hmg\SAMPLES\GRID.37

Here Grid.Save work fine.

Saludos

--

Esgici

Re: Doing Master detail in the best way..

Posted: Tue Jul 27, 2010 1:08 am
by cdsaenz
Yes, you're right! Now it works!

Well ... As usually ( bad practice but.. ) I tried a series of things at a time that solved the basic problem. Here's what I identified:

1) The function that saves from the temp file to the table would be trying to lock after appending blank... and the record was already locked. Worst, I had no message there. So it failed anonymously.

2) That same function would fill the master key with the temptable's master key... which was empty.

3) So, by now I dropped the "Save-from-temp-to-dbf" function... Usually they'll be few fields, so, no gain.

4) Grid.Save works allright of course!! Saves all pending stuff to the underlying table. Nice.

Now I'm up and running. I know I'm a pain in the neck, but I'm not satisfied with the Grid's navigation... I want a "permanent" edit state and I'll need also validation in some fields.. So I need to see if all that is possible.

EDIT: ColumnValid seems to be good for validation! I'll research on it

But we're good!

Some piece of code..

Code: Select all

/* Save master detail*/
FUNCTION JournalSave()

LOCAL nOrder, nJournal

      frmJournal.GridMaster.Save()
      IF (cEditMode == 'New')
          nJournal := VAL(DTOS(DATE()) + STRTRAN(TIME(),":",""))          
          gltr_mst->(DbAppend())
          REPLACE gltr_mst->trans_no WITH nJournal      
      ELSE 
          IF .NOT. gltr_mst->(RLOCK()) 
              msginfo("Error, registro no se puede bloquear.")
              RETURN
          ENDIF
      ENDIF
      
      REPLACE gltr_mst->period_mm  WITH  frmJournal.txtMM.Value,;
              gltr_mst->period_yy  WITH  frmJournal.txtYYYY.Value,;
              gltr_mst->trans_name WITH  frmJournal.txtName.Value,;
              gltr_mst->trans_date WITH  frmJournal.dtpDate.Value
      
      /* Temptable */        
      SET DELETED OFF
      SELECT TempDetail            
      dbGoTop()
      DO WHILE .NOT. EOF()
          SELECT gltr_det
          SEEK STR(gltr_mst->trans_no,14) + TempDetail->acc_nbr
          IF FOUND()
              /* record found in temp detail but deleted */
              /* delete in final table */              
              IF gltr_det->(rlock())
                IF TempDetail->(DELETED())                                      
                    gltr_det->(dbDelete())
                ELSE                    
                    REPLACE gltr_det->acc_nbr   WITH  TempDetail->acc_nbr
                    REPLACE gltr_det->line_amt  WITH  TempDetail->line_amt              
                    REPLACE gltr_det->trans_no  WITH  gltr_mst->trans_no                
                ENDIF
              ELSE
                msginfo("Error, registro no se puede bloquear.")
              ENDIF
                            
              gltr_det->(dbUnlock())
          ELSE
              gltr_det->(dbAppend())                              
              /*save buffer to final*/
              REPLACE gltr_det->acc_nbr   WITH  TempDetail->acc_nbr
              REPLACE gltr_det->line_amt  WITH  TempDetail->line_amt              
              REPLACE gltr_det->trans_no  WITH  gltr_mst->trans_no
              
              gltr_det->(dbUnlock())                            
          ENDIF
          
          SELECT TempDetail
          dbSkip()
      ENDDO                   
      SET DELETED ON              
              
      gltr_mst->( DbCommit() )
      gltr_det->( DbCommit() )
      // msginfo("Record was edited with success.")
      
      frmJournal.Release      

RETURN 

Re: Doing Master detail in the best way..

Posted: Tue Jul 27, 2010 1:29 am
by esgici
Hola Charly

Thanks to good news :)

Only one point for now :
cdsaenz wrote: 1) The function that saves from the temp file to the table would be trying to lock after appending blank... and the record was already locked. Worst, I had no message there. So it failed anonymously.
As far as I know, since very beginning of dBase the first rule of record locking is :

- After appending a new record system automatically put a record lock to this new record. So you don't have LOCK every new appended record before filling its fields.

And the second rule is :

- After any kind record pointer changing (skip, go, etc) , lock on record is released.

So, after appended a new record, you have either changing current record or issue an UNLOCK command.

I'm waiting your SSW (simple, short and working) sample.

Saludos

--

Esgici

Re: Doing Master detail in the best way..

Posted: Tue Jul 27, 2010 2:25 am
by cdsaenz
Thanks for the rules! Good for reminding me...
Here goes some sample. Not sure if so simple or short and specially working! :)

I've done some more progress with formats (I can't get a $ format yet.. I have to see about that)

Re: Doing Master detail in the best way..

Posted: Tue Jul 27, 2010 11:12 am
by esgici
cdsaenz wrote: Here goes some sample. Not sure if so simple or short and specially working! :)
Good work, thanks Charly :)

Let me some time for analyzing and understanding.

For now we have a little problem :
Date:27/07/10 Time: 13:41:23
Error: HMG 3.0.35 (2010.06.20)
Grid: 'RecordSource' WorkArea must be open at control definition. Program Terminated
Called from _DEFINEGRID(140)
Called from JOURNALNEW(252)
Called from (b)MAIN(26)
Called from _DOCONTROLEVENTPROCEDURE(5262)
Called from EVENTS(1434)
Called from _DOMESSAGELOOP(0)
Called from _ACTIVATEWINDOW(4853)
Called from DOMETHOD(7366)
Called from MAIN(23)
(When selecting "New" by button or from menu.)


Saludos

--

Esgici

Re: Doing Master detail in the best way..

Posted: Tue Jul 27, 2010 9:26 pm
by cdsaenz
Oh I concentrated 100% on the "edit" button so maybe I've left some buggy stuff around. Let me take a look ;)

Re: Doing Master detail in the best way..

Posted: Tue Jul 27, 2010 9:34 pm
by cdsaenz
Fixed. I guess. Replace Journals.prg with attached source.

Now ... can you take a look at line 125 of that file?
frmJournals.GridMaster.Refresh(.t.)

For some reason I need to comment out this line.. I'm quite sure it worked at first..
I think for some reason frmJournals is not visible in Journals.prg, but as it was "created" in main.prg..
shouldn't it be visible in the program below in the chain?