PDA

View Full Version : tbl pack question


ABC123

milesjg
04-10-2008, 01:35 AM
I have two tables that will compact fine when done in the control panel. When they are compacted in code, for one of the tables I keep getting the message that the index cannot be packed/rebuilt for the dictionary. Then the message - compact complete. The other table no such message/problem. Any ideas or is this to vague. ?

MikeC
04-10-2008, 01:38 AM
James,
How is the code implemented??

Stan Mathews
04-10-2008, 09:22 AM
When they are compacted in code, for one of the tables I keep getting the message that the index cannot be packed/rebuilt for the dictionary. ?This generally means that the table is open/in use. As Mike asks, what is the context? Does your code run from a button on a form based on the problem table?

Many users will create a table with one field and one record which is used for nothing other than a basis for "manu" forms. These forms contain buttons initiating code that operates on other tables where exclusive use is critical to the code.

milesjg
04-10-2008, 11:37 PM
Thanks for the replies.

- Yes the code runs from a button on a form.
- I update the indexes.
- I closed the form and the database. (a5.database.close()).
- Change directories and load another database. (Nothing else)
- Then use a5.pack_tables.
-If I place the pack_tables anywhere before loading another database I get the table in use message.
The form being closed is extremely "delete record intense" so I thought it would be a good idea to pack the tables on exit to prepare for the next session. This works for one of the tables, but the other gives the error message. The table giving the messge is a master linked to the table which goes ok. As mentioned I can compact the db from the control panel, which I don't know if has what to do with the packing.

MikeC
04-10-2008, 11:54 PM
James,
:confused: Really confused now--read, reread your post. :confused:

Two comments--

1...how can you pack tables of a closed database??? Am I unaware of this aspect of Alpha?? How would Alpha know which tables to pack??? As far as I know these things cannot be done so are said rhetorically...unless.... :)

2...I will say again what Stan mentioned. The only tables that will be packed are ones that are not open...whether it is due to a form or browse based on the table, a set that is open that contains the table or simply a form (a dialog one especially), table, or set not closed properly.

You say the pack tables script is called from a button. Is this button on a form/browse that is based on the table that won't pack? If so, then makes sense and there is NO way to correctly pack the table while it is still open. What to do? Just as Stan said...pack the table from a different form (that is based on a different table knowing that the table this form is based on will not get packed).

milesjg
04-11-2008, 12:58 AM
Well, it do not suprise me. I confuse myself most of the time anyway. But here is what I did. It is attached as a txt file. The database being closed is the one with the tables to be packed. This generates a error when the general table is packed.

MikeC
04-11-2008, 01:35 AM
ok James.
A fairly unusual method undoubtably. Once the DB is completely open go into File-->Database Properties and see if any tables are open...are either of the two tables you are trying to pack listed as being open?? If so then maybe your script which does not explicitly close the tables may be the reason...even though you would think they would close with the DB close you did I have many times witnessed the fact that tables can remain open even if the DB is not. Just a thought.

MoGrace
04-11-2008, 01:39 AM
Well, it do not suprise me. I confuse myself most of the time anyway. But here is what I did. It is attached as a txt file. The database being closed is the one with the tables to be packed. This generates a error when the general table is packed.Could it be that after you opened the tables in your script and updated their indexes, you did not close them?



tbl1 = table.open("genaccts")
tbl1.update_production_index()
tbl1.close()
sleep(.15) 'give it some time to finish

tbl2 = table.open("general")
tbl2.update_production_index()
tbl2.close()
sleep(.15)

parentform.close()
sleep(.15)

a5.Database_Close()

file.dir_put("c:\Estimate")

:a5.load("c:\Estimate\Screens.adb")

a5_pack_table("c:\estimate\setup\general accounts\general.dbf")
a5_pack_table("c:\estimate\setup\general accounts\genaccts.dbf")

Form.view("SETUP OPENING SCREEN")The help is not very clear whether the new a5_pack_table() opens the table in order to pack it or not and then closes it. The old <tbl>.pack() command needed to point to an open table.

martinwcole
04-11-2008, 05:21 PM
1. If you go to the controlpanel of a database, and try to pack a table, and it replies the table is in use, generally that means you left it open somewhere. (One thing to look at though is whether you have been using operations for the table before you tries to pack - as in any other event since the last time you opened the data base. Not sure if the issue is still around, but there was a point when operations would sometines not close a table, and developers were converting the operations to xbasic - which eliminated the problem.)

2. a5.load("c:\Estimate\Screens.adb") automatically closes the current adb before opening the next one, so closing it is not only unnecessary but could cause problems.

3. If you use a5_pack_table("c:\estimate\setup\general accounts\general.dbf") you do not need to open the tables first. And you do not need to rebuild the indexes, as this not only removes deleted records but also refreshed the indexes.

milesjg
04-11-2008, 05:21 PM
Even if tbl.close() is used the tables are still open. By running debug before the code and stepping through, the isopen() shows the tables open untill another db is loaded.

tbl.close()
parentform.close()
a5.database_close()
' change directory
' load another db.

In debug isopen() and in_use() show tables as open until after the load another db occurs.
The genaccts table presents no problem. Just the other one. It has to have something to do with it being a master in a link. Although I did create another set and both tables had no problem. Must be the table. Will delete and remake it. Thanks for the interest.

milesjg
04-11-2008, 05:34 PM
Martin;

There are no operations being run on the tables prior to running this code segment. There will be in actual use,but I have'nt touched the tables while trying to resolve this.
The reason I redid the indexes was that both tables gave me the error message until I did. (This was after running operations on the tables) After the redo on the index no problem. So I left it in. I opened the tables prior to the a5_pack, but issued the tbl.close() before the form was closed, which did not close the tables (isopen in debug show .T.) I put the a5_db_close in a attempt to close the tables (which did not work) so as to run the packing before the next db was loaded.

martinwcole
04-11-2008, 05:45 PM
ok - it sounds like the issue is in the operations.
Do this:

Open the adb fresh, and do a database compact.

If all tables pack ok - go to the index definitions for those tables and see if all the indexes still exist. (Historically - an impossible query would cause Alpha to actually delete an index, and operations typically include a query/filter.)

If all the tables don't pack ok - close the adb and then open it again, and try it again.

If they don't all pack - then you have a different issue.

If they do - do whatever you do that has the operation(s) run. Go to the control panel, and see if the tables will pack, and the indexes are still there.

added PS: be sure the form where you are running the indexrebuild/table pack from IS NOT bases on any of the tables in question or a set including same.

martinwcole
04-11-2008, 05:54 PM
Mike, just for the record, you CAN open tables in adb "B" from adb "A" and do basically anything you want. I have a scenario where there are about 10 different adbs on a server - one each for individual hospitals/clinics/living centers, etc. And from a separate adb that runs nightly at a specified time does maintenance on each of the 10 adbs - all are in their own folders.

MikeC
04-12-2008, 12:39 AM
Martin, nice to know! I imagine that you just have to use the complete path to the unopened DB when referencing any table within the unopened application/database then.

Anyway--one thing not asked or mentioned is --is the form causing the problem by chance opened as a dialog form?? So many times this is the cause of a table being left open.

DaveM
04-12-2008, 10:31 AM
a seperate adb with those tables mentioned to be packed and a dummy table(that does not get packed) and form with the button can solve all of this. Open the extra adb, only the dummy table will be open, run the pack operation on all the tables and close the adb.

It can also be set up as automatic with the autoexec script in the seperate adb so there is no form. This can be run after the main adb is closed with an ondatabaseclose script.

This is in theory.

I rarely have to pack tables, but start the adb with a form on a table that has one record only. any packing is done from here. Once tables are opened and worked with, it will not run(sets a var to .t. so the pack button does nothing)

MoGrace
04-12-2008, 05:43 PM
Hi Dave,
I use a script on an exit button for the program which closes open forms & enumerates all the tables and checks for deleted records and if any are found packs the tables. But I have an option to skip the routine and just close. I like your idea better since it ensures each session starts with everything in good shape. It would make the load longer in the a.m., but wanting to go home quickly at the end of the day could be done without causing anyone grief.

EricN
06-11-2008, 05:24 PM
I'm curious why this method is not suggested.

table_list = <<%list%
mytable1
mytable2
mytable3
%list%

table_list = *for_each(x, "[PathAlias.ADB_Path]" + chr(92) + x + ".dbf",table_list)
in_use = *for_each(x, x + "|" + table.in_use(x), table_list)

tables_to_update = filter_string(in_use, "|False", crlf())
tables_to_update = stritran(tables_to_update, "|False", "")

dim count as n
count = w_count(tables_to_update,crlf())
dim i as n
dim tbl as p
for i = 1 to count
table_i = word(tables_to_update,i,crlf())
tbl = table.open(table_i)
tbl.pack()
tbl.close()
next i

Or am I missing somthing?

EricN
06-11-2008, 07:00 PM
Sorry. Didn't realize this post was in the desktop forum. I was doing a search for "pack" and that is how I found this post.