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
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?