Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3020
  • Last Modified:

How to simulate clicking View then Refresh (F5) in Access in VBA

After deleting several linked tables and adding several more via VBA, I need a way to simulate clicking Refresh from the View menu via VBA.  When I first open a query after doing my deletions and additions, it tells me it can't find the underlying tables.  Then when I click OK and try again it works because it must trigger a refresh in doing that.  How can I do it via VBA?
0
woodmacnaps
Asked:
woodmacnaps
  • 11
  • 10
  • 8
1 Solution
 
Rey Obrero (Capricorn1)Commented:
add this line to your codes


application.RefreshDatabaseWindow
0
 
woodmacnapsAuthor Commented:
I tried this and am still getting the same behavior.....doesn't work the first time I ty to open a query but works every other time.  I even put this line of code as the very last line to be executed and still didn' seem to make a difference?
0
 
Rey Obrero (Capricorn1)Commented:
post the codes that you are running.
0
Restore individual SQL databases with ease

Veeam Explorer for Microsoft SQL Server delivers an easy-to-use, wizard-driven interface for restoring your databases from a backup. No expert SQL background required. Web interface provides a complete view of all available SQL databases to simplify the recovery of lost database

 
woodmacnapsAuthor Commented:
Function relink_working_folder_f()

strStatus = "Please wait while Multi_Work.mdb is updating all linked tables for the files in this folder..."
varStatus = SysCmd(acSysCmdSetStatus, strStatus)

'Turn Screen Updating off
Application.Echo False
DoCmd.Hourglass True

define_working_files_to_link
'Load in current working directory to begin processing multiple output
pathvar = CurrentProject.FullName
filenamevar = CurrentProject.Name
curdirvar = Mid(pathvar, 1, Len(pathvar) - Len(filenamevar) - 1)

Dim detailfilename As String
Let detailfilename = "Multi_Work_Detail.mdb"

Dim comparetblname As String
Let comparetblname = "Compare Databases"

update_log_file "Beginning linking of compare detail table."

'Load in current database as object
Dim obj As AccessObject, dbs As Object
Set dbs = Application.CurrentData
Dim dbSel As dao.Database
Set dbSel = CurrentDb()

'Remove any tables that match the current table prefix
update_log_file "Beginning removal of old compare detail table."
For Each obj In dbs.AllTables
    If obj.Name = comparetblname Then
        update_log_file "Removed table '" & obj.Name & "'."
        DoCmd.DeleteObject acTable, obj.Name
    End If
Next
update_log_file "Completed removal of old compare detail table."

Set obj = Nothing
Set dbs = Nothing

'Now open dbname database and link each table in it to this database
Dim db As dao.Database
Dim tds As dao.TableDefs
Dim tdf As dao.TableDef

Set db = OpenDatabase(curdirvar & "\" & detailfilename)
Set tds = db.TableDefs

update_log_file "Beginning linking of new compare detail table."
For Each tdf In tds
    'Only interested in non-system tables, which aren't linked
    If tdf.Name = comparetblname Then
        'Create a new table def, named as per the target table
        Set tdflink = dbSel.CreateTableDef(tdf.Name)
        'Identify the target table for the link
        tdflink.SourceTableName = tdf.Name
        'Identify its path
        tdflink.Connect = ";DATABASE=" & curdirvar & "\" & detailfilename
        'And add it to this database's tables
        dbSel.TableDefs.Append tdflink
        tdflink.RefreshLink
    End If
Next

update_log_file "Completed linking of new compare detail table."

'Close out variables
Set dbSel = Nothing

Set tdf = Nothing
Set tdflink = Nothing
Set tds = Nothing
db.Close
Set db = Nothing

update_log_file "Completed linking of compare detail table."
'Turn Screen Updating back on
DoCmd.Hourglass False
Application.Echo True

Application.RefreshDatabaseWindow

strStatus = "Ready"
varStatus = SysCmd(acSysCmdSetStatus, strStatus)

End Function
0
 
Rey Obrero (Capricorn1)Commented:
modify your codes

For Each obj In dbs.AllTables
    If obj.Name = comparetblname Then
        update_log_file "Removed table '" & obj.Name & "'."
        DoCmd.DeleteObject acTable, obj.Name
    End If
Next

Application.RefreshDatabaseWindow  ' <<< Add here


post back the result
0
 
woodmacnapsAuthor Commented:
it still is acting the same way....should I be activating a certain window first or something?  
0
 
Rey Obrero (Capricorn1)Commented:
what does this line do

    update_log_file
0
 
datAdrenalineCommented:
>> Then when I click OK and try again it works because it must trigger a refresh in doing that. <<

Do you have the Name AutoCorrect option enabled?  If so, then turn it OFF!  Also, apparently you do not have Option Explicit set at the top of your module ... I would suggest that you add that in order to ensure proper variable name usage.

Looking at your code now ...

0
 
woodmacnapsAuthor Commented:
>> update_log_file <<

Simply writes out a line to a log telling what the code is doing as it loops though objects...

Function update_log_file(logmessagevar)

'Load in current working directory
pathvar = CurrentProject.FullName
filenamevar = CurrentProject.Name
curdirvar = Mid(pathvar, 1, Len(pathvar) - Len(filenamevar) - 1)

'Code to write to log file
Dim iFileNumber As Long
Dim strFileName As String
Dim logfilenamevar
Dim sepvar
'Load in timestamp information
curtime = Now()

'Determine separator value
If Len(curtime) = 19 Then
    sepvar = "~~~~"
End If
If Len(curtime) = 20 Then
    sepvar = "~~~"
End If
If Len(curtime) = 21 Then
    sepvar = "~~"
End If
If Len(curtime) = 22 Then
    sepvar = "~"
End If

'Text to write to log file
strdata = curtime & " " & sepvar & " " & logmessagevar

'Update first log file
'Load in log file names
logfilenamevar = "Woodmac_CMS_Process.log"
iFileNumber = FreeFile()
strFileName = curdirvar & "\" & logfilenamevar
Open strFileName For Append Shared As #iFileNumber
Print #iFileNumber, strdata
Close #iFileNumber

End Function


0
 
datAdrenalineCommented:
You are doing a lot of work in your code to delete and recreate one linked table object.  You can simply modify the .Connect property of the existing table.

Function relink_working_folder_f()
   
    Dim strDetailFileName As String
    Dim strCompareTblName As String
    Dim strConnection As String

    strDetailFileName = "Multi_Work_Detail.mdb"
    strCompareTblName = "Compare Databases"
    strConnection = ";DATABASE=" & CurrentProject.Path & "\" & strDetailFileName    
   
    With CurrentDb
        With .TableDefs(strCompareTblName)
            .Connect = strConnection
            .RefreshLink
        End With
    End With
End Sub

By modifying the .Connect property, there is no need to delete and recreate the object.  By keeping your objects and just modifying the properties, you reduce your risk of corruption and bloating.
0
 
datAdrenalineCommented:
Sorry that was supposed to be End Function (the code was written "on the fly") -- BTW, any reason you are not using a Sub (as appossed to a Function)?

Function relink_working_folder_f()
   
    Dim strDetailFileName As String
    Dim strCompareTblName As String
    Dim strConnection As String

    strDetailFileName = "Multi_Work_Detail.mdb"
    strCompareTblName = "Compare Databases"
    strConnection = ";DATABASE=" & CurrentProject.Path & "\" & strDetailFileName    
   
    With CurrentDb
        With .TableDefs(strCompareTblName)
            .Connect = strConnection
            .RefreshLink
        End With
    End With

End Function
0
 
woodmacnapsAuthor Commented:
Thanks for your comments on how I wrote that piece of code.  That's not the issue I am having though.  It works fine as-is and was originally written for a more dynamic process of removing all linked tables and adding those of a completely different database with different tables, etc.  They are always different.  The problem is refreshing the database so it recognizes tables I have added and deleted via code.
0
 
Rey Obrero (Capricorn1)Commented:
try also adding the line after these codes

For Each tdf In tds
    'Only interested in non-system tables, which aren't linked
    If tdf.Name = comparetblname Then
        'Create a new table def, named as per the target table
        Set tdflink = dbSel.CreateTableDef(tdf.Name)
        'Identify the target table for the link
        tdflink.SourceTableName = tdf.Name
        'Identify its path
        tdflink.Connect = ";DATABASE=" & curdirvar & "\" & detailfilename
        'And add it to this database's tables
        dbSel.TableDefs.Append tdflink
        tdflink.RefreshLink
    End If

Application.RefreshDatabaseWindow  ' <<< Add here

Next


post back the result

0
 
woodmacnapsAuthor Commented:
I think it must be a timing issue.  If I do none of these changes and simply wait about 5 seconds, it works the first time.  If I try to open it immediately i get the same old error.  No matter what I try, it doesn't seem to resolve that issue.
0
 
Rey Obrero (Capricorn1)Commented:
where particularly is the error appearing?
0
 
datAdrenalineCommented:
>> It works fine as-is and was originally written for a more dynamic process of removing all linked tables and adding those of a completely different database with different tables, etc. <<

I was just going by the code you posted ... :)

Take a look at the following code.  It is a modification of yours.
Things to note:
- The use of CurrentProject.Path
- The "Step -1" looping to delete the linked tables in the dbSel.TableDefs collection.
- The dbSel.TableDefs.Refresh call in order to refresh the TableDefs collection of dbSel.
- The placement of the RefreshDatabaseWindow in the loop that adds the tabledefs to the current database.  Plus the one "extra" at the end (just as you had it).
- No need to call .RefreshLink when creating a linked table object.  The .Append takes care of that.

<< Biggest note of all! ... this is AIR CODE as I did not test this code in an actual database :-s >>

Take a look and see if it solves the issue you are having.  Also, PLEASE make sure you have the Name AutoCorrect option disabled .. otherwise the dependancy mapper may get confused with adding and deleting objects, especially if the names of the linked tables are the same.

Function relink_working_folder_f()
   
    Dim strStatus As String
    strStatus = "Please wait while Multi_Work.mdb is updating all linked tables for the files in this folder..."
   
    Dim varStatus As Variant
    varStatus = SysCmd(acSysCmdSetStatus, strStatus)

    'Turn Screen Updating off
    Application.Echo False
    DoCmd.Hourglass True

    define_working_files_to_link
   
    'Load in current working directory to begin processing multiple output
    Dim curdirvar As String
    curdirvar = CurrentProject.Path

    Dim detailfilename As String
    Let detailfilename = "Multi_Work_Detail.mdb"

    Dim comparetblname As String
    Let comparetblname = "Compare Databases"

    update_log_file "Beginning linking of compare detail table."

    'Load in current database as object
    Dim dbSel As DAO.Database
    Set dbSel = CurrentDb()

    'Remove any tables that match the current table prefix
    'notice the reverse looping because when you loop a collection
    'for removal, its safest to remove based on the highest index.
    update_log_file "Beginning removal of old compare detail table."
    Dim x As Long
    For x = dbSel.TableDefs.Count - 1 To 0 Step -1
        If dbSel.TableDefs(x).Name = comparetblname Then
            update_log_file "Removed table '" & obj.Name & "'."
            DoCmd.DeleteObject acTable, obj.Name 'Automatically refreshes dbwindow
        End If
    Next
    update_log_file "Completed removal of old compare detail table."

    'Refresh the TableDefs collection of the db object variable that points to
    'the current db.
    dbSel.TableDefs.Refresh

    'Now open dbname database and link each table in it to this database
    Dim db As DAO.Database
    Set db = OpenDatabase(curdirvar & "\" & detailfilename)
   
    update_log_file "Beginning linking of new compare detail table."
   
    Dim tdf As DAO.TableDef
    For Each tdf In db.TableDefs
   
        'Only interested in non-system tables, which aren't linked
        If tdf.Name = comparetblname Then
           
            'Create a new table def, named as per the target table
            Dim tdflink As DAO.TableDef
            Set tdflink = dbSel.CreateTableDef(tdf.Name)
           
            'Identify the target table for the link
            tdflink.SourceTableName = tdf.Name
           
            'Identify its path
            tdflink.Connect = ";DATABASE=" & db.Name
           
            'And add it to this database's tables
            dbSel.TableDefs.Append tdflink
            Set tdflink = Nothing
           
            'Refresh the dbwindow/navpan
            RefreshDatabaseWindow
           
        End If
       
       
    Next
   
    db.Close
    Set db = Nothing
   
    update_log_file "Completed linking of new compare detail table."

    'Turn Screen Updating back on
    DoCmd.Hourglass False
    Application.Echo True
   
    'A refresh to just be sure
    RefreshDatabaseWindow

    strStatus = "Ready"
    varStatus = SysCmd(acSysCmdSetStatus, strStatus)

End Function
0
 
datAdrenalineCommented:
>> If I do none of these changes and simply wait about 5 seconds, it works the first time.  <<

This is why I made the comment about Name AutoCorrect ... I never have the option enabled, but the delay may be due to the dependancy mapper figuring out what to do with all the new linked table objects.
0
 
woodmacnapsAuthor Commented:
Yes I turned that off and still have the same error.  It is only when I try to "immediately" open a query that was dependent on the underlying tables that have been erased and brought back.  If I simply wait 5 or 6 seconds and then open it, no error.  I'm sure there is something simple I am missing here.  I'll take a hard look at the revidescode you gave me here and see if it still accomplishes my goal and hopefully fixes the issue with the timing error.
0
 
datAdrenalineCommented:
Cool! ... Cap and I are looking forward to the results.

---

Also, one more thing in trying to debug the delay in tabledefs being "available" for the Query, do you open the Query object from the database window? or in code?
0
 
woodmacnapsAuthor Commented:
I open it manually at the moment, but that is the intent for resolving this issue.  The whole idea behind this code is it will link multiple databses of like structure all to one file so that the like tables can all be joined with unions in SQL code and the resultant queries will then be created automatically and is completely flexible to the number of like databases.  We use this in comparing multiple forecasts at once that are all in the exact same format, just different numbers.  Just throw all of the output mdb files into one directory and open this file and all data is linked and available to build comparison queries off of.  Just a little background info for you on what I am trying to do here.
0
 
Rey Obrero (Capricorn1)Commented:
Perhaps, a delay before running the codes will help resolve the issue.
0
 
datAdrenalineCommented:
>> Just a little background info for you on what I am trying to do here.  <<

Thanks for that!  Sometimes the additional detail can lead to a suggestion that renders the original question obsolete! :) ... with that spirit in mind, you MAY want to consider the fact that in order to peer into another database, you really don't need Linked Table objects.  You can use what I call a "fully qualified" Jet/ACE SQL syntax ...

For example: To read data from someTable in someDatabase.mdb which is in someFolder, you can use a Query Object with an SQL statement that looks like this:

SELECT * FROM someTable IN '' [MS Access;DATABASE=C:\someFolder\someDatabase.mdb]
or
SELECT * FROM someTable IN 'C:\someFolder\someDatabase.mdb'
or
SELECT *
FROM (SELECT *
FROM  someTable IN '' [C:\someTable\someDatabase.mdb]) As vTbl
or
|-->SELECT * FROM [C:\someFolder\someDatabase.mdb].someTable
| or
|--> SELECT * FROM [MS Access;DATABASE=C:\someFolder\someDatabase.mdb].someTable
|-- Note in A2007 and prior, if you save a Query Object with this type of syntax (the last two listed), MS Access will modify the SQL View to a string that is not valid syntax, but it will still run -- until you change the string :-s ... but if you are doing the manipulation of the SQL property of a QueryDef object, then there should be no need to open the Query Object in design view for anything.

The reason I bring up this ability is that you can use a single Query Object to JOIN or UNION data from several different database.  And if you use code to modify the SQL property of a QueryDef object with the code line of code being:

CurrentDb.QueryDefs("someQueryObject").SQL = "some valid SQL statement"

You can create some fantastic Query Objects or SQL statements without having to mess with the creation and deletion of Linked Table objects.  For Example:

SELECT "Database1.mdb" As SourceDb, Field1, Field2, Field3 FROM [C:\someFolder\Database1.mdb].someTable
UNION ALL SELECT "Database2.mdb" As SourceDb, Field1, Field2, Field3 FROM [C:\someFolder\Database2.mdb].someTable

Or ..

SELECT db1.Field1 As db1Fld1, db2.Field1 As db2Fld1
FROM (SELECT Field1 FROM [C:\someFolder\Database1.mdb].someTable) As db1
INNER JOIN
(SELECT Field1 FROM [C:\someFolder\Database2.mdb].someTable) As db2
ON db1.someKeyField = db2.someKeyField

I find that when I compare databases or use multiple data sources in the same application, especially when the sources have the same table names -- I use the Query Object (QueryDef) route heavily.   I actually have distributed apps the have NO Table Objects -- and just a few Query Objects.  The large majority of the datasource was done with SQL statements in the RecordSource property of the Form/Report and RowSource property of a Combo/List box.

If this ability will not fit for your current need, its definately good to know that you can, then possibly use it in a future app.
0
 
woodmacnapsAuthor Commented:
Very intuitive and very useful for my needs here.  I may go down this route as it will speed up the whole"linking" process that buils the queries....since there won't even be any more linking involved, just SQL syntax....thanks!
0
 
woodmacnapsAuthor Commented:
One of the benfits of linking tables is that when you run queries off of linked tables you get no Access CREEP in the current file or the source file....is that still the case when using queries that link to other files like you demonstrated here?
0
 
datAdrenalineCommented:
I have never had an issue -- if your are talking about bloating of the database files.   If you are not putting any data into the source files then there should be virtually no growth in there size.  The client file (the one running the SQL's) might be more prone to growth -- it just depends on what you are doing with your objects and local data (if any exists).  With your original thought of deleting and recreating the Linked Table Objects, your client db (aka: application database) would be prone to bloating because of the constant creation of objects.  The way database files work, in short, is that they will never shrink barring any "external" process.  A database will claim disk space it needs to store the data or objects it needs to store.  Deleting data or objects do NOT free up the database file claim on the hard drive.  Thus the need for the Compact and Repair operation (in SQL server, the same phenomenon exists).  The C&R is sorta like a defrag of your database -- it reorganizes all the data in order to release the unused space back to the hard drive.
0
 
datAdrenalineCommented:
... Continuing ...

The reason my initial suggestion to modify the .Connect property of the linked table object was to reduce the bloating of the application database file.  So ... if you use the Query Object route, I would suggest creating the Query Objects you need, then just modify the SQL property of the QueryDef object.  Or, as I stated earlier, just use SQL statements in source type properties (RecordSource, RowSource) or the raw SQL statement to build recordsets in VBA.
0
 
woodmacnapsAuthor Commented:
Yep, I have decided to go the route of simply creating the SQL statements via VBA and do away the linking and relinking.  Much cleaner and faster.  Thank you s much for the redirection here.  Learn something new everday!
0
 
datAdrenalineCommented:
You're welcome!

Its definately good to learn more stuff -- that is why I like EE and other sites like it, its amazing the solutions that folks can come up with!  Always good to learn new stuff.

Good luck on your project!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 11
  • 10
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now