Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
MSQuery
Message
De
02/07/2003 07:56:42
Cetin Basoz
Engineerica Inc.
Izmir, Turquie
 
 
À
01/07/2003 11:07:32
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Titre:
Divers
Thread ID:
00805557
Message ID:
00806011
Vues:
29
>Thank you very much for your quick response. I’ll try to do a better job of explaining my current situation.
>
>I started with a VFP 6.0 database on one computer being merged to several different Word 97 documents either through MSQuery or Excel through MSQuery (if there were a lot of fields being merged). I found it to be very slow merging through Excel and then into Word in order to accommodate the restriction of the 255 SQL character limitation using MSQuery. However, I was able to deal with that as I was the only one using the computer.
>
>Now, I have a VFP 6.0 database that is shared over two computers in a client/server network (really a peer to peer network, but the database is only on the host computer which I was working on). I was unable to figure out how to merge a document over the network (ie the client has the Word document, and the Server has the VFP database). I contacted Microsoft, and they talked me through one solution. They said I could have the same copy of the database on both computers. When, in a form, someone clicks the save button in order to add values to a table, the save button updates both the table on the server, and the table on the client. The client copy of the database and the server copy of the database will therefore always be identical, and the merged documents will merge to the database on the local computer. As you can imagine, making changes and saving to two computers can become slow, but at the time, it did accomplish my objective.
>
>Now, the speed is starting to become an issue. In order to do a workaround, I created a program that selects the data to be merged into a free table. Foxpro is able to merge into a free table without needing MSQuery, and there are no limits (as far as I know) on the number of characters in the SQL statement. In order to have the free table updated whenever changes are made to the original database, I run the program every time a change is made to the dababase information (I issue a “do program” statement in the “save” button of a form). Therefore, the free table is always up to date. The only problem with this solution is that once one person (say the client) updates the free table, the other person (the server) cannot update the free table since utilizing the “select into table” command causes the other computer to get a “file in use” error.
>
>I am not sure if this is clear, but I am not a “great” programmer. As of three years ago, I did not even know what a database is! However, I have learned a lot and enjoy learning and fixing problems with my programs. This is a problem that I have had for over a year and have not been able to solve. Unfortunately, I am not sure what you are referring to with your "Sys" command to change the name of the free table. I am not sure if it applies based on my current situation which I hope I clarified a bit better above. The 255 character limit is the SQL limit, and I have never been able to figure out how to utilize the SQL and SQL1 statements (ie how to combine them into one statement - do you use the first SQL statement to select into a cursor and then use the SQL1 statement to select * from the cursor along with additional fields from the database?)
>
>I would really appreciate either a solution to the “file in use” problem (ie being able to run the “select into table” program on different computers concurrently without getting this error), or an alternative to MSQuery. Thank you very much for your help.
>
>Paul

Paul,
I'm not sure about the solution MS provided. Sounds a bit strange way of doing it but anyways if it's working as you want no problem.
For merge source there are 2 SQL strings. With 2 strings actually all you do is to split and put first 255 chars into first and rest into second. ie:

lcOriginalSQL = 'select .... from ...' && Assume would be over 255 in length
lcSQL1 = left( lcOriginalSQL, 255 ) && First 255 chars
lcSQL2 = substr( lcOriginalSQL, 256 ) && Rest

However what I do is to create the free table with my SQL in VFP therefore free from the limits (limits exist in VFP too but at least I couldn't hit those limits yet). Then for word source I simply use an SQL like :

select * from MyAlreadyVFPSQLedTable

IOW I do real SQL on VFP with all joins, fields, filters etc. and then on word select all from that free table. VFP being much faster on SQL then word with ODBC the result is fast (or even faster than doing only with ODBC).

Check downloads for a 'Mail merge with word' class. I wrote that years ago, before MDAC 2.1 came out. With MDAC 2.1 release drivers needed were dropped but it should still be working (or you might change DSN setting there with the one below).

The solution with sys(2015) creates unique free tables per user. ie:
lcFreeTableName = "F"+Sys(2015) && Create a temp table name

* Get data as a regular VFP SQL into a free table (temporary)
* You could do any joining, filtering etc with data fields
* needed for your merge here - limit is 8K AFAIK

Select * From employee ;
  where Title = 'Sales' ;
  into Table (lcFreeTableName)	&& Select recs into a temp table

cDataSource = Dbf(Alias()) && Save fullpath in order to erase later 

* Prepare DSN string
cDSN = "DSN=Visual Foxpro Tables;DBQ="+Sys(5)+Curdir()+;
  ";DefaultDir="+Sys(5)+Curdir()+";"+;
  "SourceDB="+lcDefDir+";SourceType=DBF;"

cSQLStatement = "SELECT * FROM "+lcFreeTableName+".dbf"
USE && Close the table

* Now free table is created and ready for merging

#Define wdSendToEmail  2
#Define wdSendToFax  3
#Define wdSendToNewDocument  0
#Define wdSendToPrinter  1
#Define wdDoNotSaveChanges	0
#Define wdSaveChanges	-1

*** set the LOCALEID to English
nlLocaleId=Sys(3004)		&& Save local id
=Sys(3006,1033)				&& We will be sending instructions in English
Wait Window Nowait "Creating Word Document..."     && Inform user
Local llToPrinter
oWordDocument=Createobject("word.application")	&& Create word object
With oWordDocument
  .Documents.Add(Sys(5)+Curdir()+'mytemplate.dot') && Use a predefined template
  With .ActiveDocument.MailMerge
    .OpenDataSource(,,,,,,,,,,,cDSN, cSQLStatement) && Open data source
    If llToPrinter
      .Application.Options.PrintBackGround = .T.
      .Destination = wdSendToPrinter
    Else
      .Destination = wdSendToNewDocument
    Endif
    .Execute
  Endwith
  Wait Clear
  .Visible = !llToPrinter
Endwith
If llToPrinter
  oWatcher = Createobject('myTimer')
Else
  oWatcher = Createobject('myTimer2')
Endif
Read Events
Messagebox('Word finished')
? cDataSource
Erase (cDataSource)


**** Set the LocaleId to the previous value
=Sys(3006,Val(nlLocaleId))

Define Class myTimer As Timer
  Interval = 1000
  Procedure Timer
    With oWordDocument
      If .BackgroundPrintingStatus > 0 && Wait printing to finish
        Return
      Endif
      For Each oDoc In .Documents
        oDoc.Close(wdDoNotSaveChanges)
      Endfor
      oDoc = .Null.
      .Quit(wdDoNotSaveChanges)
    Endwith
    This.Enabled = .F.
    Clear Events
  Endproc
Enddefine

Define Class myTimer2 As Timer
  Interval = 1000
  Procedure Timer
    If Type('oWordDocument.Documents') = 'O' And ;
        oWordDocument.Documents.Count > 0
      Return
    Endif
    This.Enabled = .F.
    Clear Events
  Endproc
Enddefine
PS: Actually in a multiuser environment sys(2015) value might be duplicated. But chances are very low with a task like this and additionally using local directory (sys(5)+curdir()) to create the table the chance is eliminated. I assume exe file is on each user's local folder (which should be for performance reasons if nothing else).
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform