Solved

Crystal Reports Viewer ActiveX Control in Visual FoxPro 9 Keeping Foxpro Tables Open

Posted on 2011-04-05
1,370 Views
Last Modified: 2012-05-11
We have a form in our software package that runs the Crystal Reports Viewer 9.2 ActiveX control written in Visual FoxPro 9 SP2. The crystal reports we use have been written to read our VFP table data through ODBC. The crystal reports viewer works well, as I've used Experts' Exchange several times to get that piece to operate.

However, we have several features in our software that requre large and secure transaction processing, therefore we sometime need exclusive use of specific tables in our database. Since our application is typically shared over a network by many users, one user might have the crystal report viewer open with a report that uses a table which another user needs to use exclusively.

My question is: can the crystal reports viewer (or perhaps the crystal reports themselves) be written to close the VFP tables it uses once the report has been run without having to completely close the form containing the crystal report viewer?

I have tried to read the DownloadFinished property of the ActiveX control, but that has never returned true. Perhaps there is another property I can read, or a method I can run to close the VFP tables or data connection without having to close the resulting report.

FYI - These same reports, when run with the full Crystal Reports 2008 also leaves the VFP tables open without being able to get exclusive use.
0
Question by:ContrAcct
    8 Comments
     
    LVL 99

    Accepted Solution

    by:
    As far as I know, you can't control whether the tables remain open or not.  The data control is internal to the viewer or runtime engine.

    There is a method you can use to run reports but it probably would require you to rebuild the reports.
    It allows you to pass a dataset from the application to the report thus the database doesn't need to remain open.

    Another idea would be to change where the reports get the data to a temp database.  In this idea you would copy the data or tables you need to another database, perhaps in the users local space, then run the report from that database.  I know of at least 1 application that does that.

    mlmcc
    0
     
    LVL 41

    Expert Comment

    by:pcelba
    Analogically to opening the connection you should be able to close it. VFP ODBC driver supports this functionality.

    A work around exists, of course: you may close open tables by calling VFP trigger fired on a table designed for this purpose...
    0
     
    LVL 99

    Expert Comment

    by:mlmcc
    The problem is you arent opening the connection in code, the report  or the viewer is opening it.

    You may be able to close the connection but then if the user wants to view a different page, you may not be able to or you will have to reopen the connection.

    In earlier versions of Crystal the connection could even remain open for 15-20 minutes after you closed the report.

    mlmcc
    0
     

    Author Comment

    by:ContrAcct
    "A work around exists, of course: you may close open tables by calling VFP trigger fired on a table designed for this purpose..."

    pcelba, could you please explain your work-around further? I don't understand how to do that.
    0
     
    LVL 29

    Expert Comment

    by:Olaf Doschke
    Don't know how you would establich a table trigger to close tables, as Crystal report only reads data and there is no select-trigger, only insert, update and delete, all operations Crystal does not do on data.

    Also via VFP ODBC you can't connect to a DBC with DBC-Triggers, otherwise you could program some routine running on an OpenTable event.

    I don't use Crystal Reports but I think you can run stored procedures instead of sql queries. So you could put data retrieval into such a stored procedure, that will query data into a cursor it creates and afterwards could already close tables. That would be an option.

    If you have no DBC, then create one. Tables don't necessarily need to be added to it, you can use ot to simply have your data access code as VFP code in a stored proc. Don't ask me though, how to modfiy your reports to call stored procs instead of direct querying of data.

    Besides this, why should that matter? Even if you use technical transactions BEGIN TRANSACTION ... END TRANSACTION is possible on tables used shared. There are operations like PACK or ALTER TABLE needing exclusive access, but not transactions, otherwise the concept of transactions would be quite useless.

    What's true is, that transactions can lock out others, but not from read operations, so a report can run, while a transaction takes place, it will only not see all data modified ar added by the running transaction unless it's committed.

    Bye, Olaf.

    0
     
    LVL 41

    Expert Comment

    by:pcelba
    I've missed the question, sorry.

    To close tables in the trigger is very easy. But it seems it will be better to create an UDF instead of trigger, so:
    1) Suppose you have the Datbase container (DBC) already created
    2) Create a table (e.g. DummyClose) having one column of any data type
    3) Add one record into this table, value is not relevant
    4) Create a user defined function in the DBC:

    FUNCTION CloseTable
    LPARAMETER lcAlias

    IF USED(ALLTRIM(lcAlias))
      USE IN (ALLTRIM(lcAlias))
      RETURN .T.
    ELSE
      RETURN .F.
    ENDIF


    And now you may close any open table(s) by executing the following command:

    SELECT CloseTable("MyFirstAlias"), CloseTable("MySecondAlias") FROM DummyClose

    The only table you cannot close by above command is the DummyClose itself.
    0
     
    LVL 41

    Expert Comment

    by:pcelba
    Of course, you may update the function to close all tables open in the current connection:

    FUNCTION CloseAllTables

    LOCAL lnAliases, lnI, laTbl[1], lnCloseCount

    lnAliases = AUSED(laTbl)
    lnCloseCount = lnAliases * 1000

    FOR lnI = 1 TO lnAliases
      IF RIGHT(DBF(laTbl[lnI,1]), 4) <> ".TMP"
        IF ! "DUMMYCLOSE" $ DBF(laTbl[lnI,1])
          USE IN (laTbl[lnI,1])
          lnCloseCount = lnCloseCount + 1
        ENDIF
      ENDIF
    NEXT

    RETURN lnCloseCount

    The return value informs about the total number of open tables and also about the number of tables closed by the function call.
    0
     
    LVL 99

    Expert Comment

    by:mlmcc
    This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    Cisco Complete Network Certification Training

    If you’re an IT engineer or technician, it's time you take your career to the next level. This elite training bundle is brimming with all of the information you need to learn to sit for Cisco CNNA, CCNP, and CCENT certification exams.

    Hot fix for .Net Crystal Reports 10.2.3600.0 to fix problems with sub reports running on 64 bit operating systems ISSUE: Reports which contain subreports fail with error "Missing Parameter Value" DEPLOYMENT SERVER OS: Windows 2008 with 64 bi…
    Microsoft Visual FoxPro (short VFP) is a programming language with it’s own IDE and database, ranking somewhat between Access and VB.NET + SQL Server (Express). Product Description: http://msdn.microsoft.com/en-us/vfoxpro/default.aspx (http://msd…
    With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…
    Want to make your posted content more private? Follow these quick and easy steps to change the display name associated with your posted content.

    678 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    28 Experts available now in Live!

    Get 1:1 Help Now