Lag in data being updated

I have to do some minor, or so I thought, summing of detail amounts entered in a subform and placing the sum on the transaction header record.    But, most of the time, amounts were updating one record behind were they were supposed be updating.  

I spent hours trying to figure out what was going on what with debug.print statements with embedded Now()s, verified that the record ID of queries being passed to the VBA code was correct and so on and so forth.  The debug.prints on the subform and the code were clearly showing I had the correct Autonumber record ID.  The amounts in the debug.print behind the subform were showing the correct values but the code running the SQL query to do the update was showing the old record values.

I put the code in behind a command button on the form and it worked as expected.

I knew it was something stupid.  And sure enough it was.

I was running the code to update the transaction header record in the controls AfterUpdate event.   I should’ve been running the code in the forms AfterUpdate event.   Duhhh!!!! 

The debug.print in the AfterUpdate event was showing the value of the control and not the value of the field in the record because the update from the form to the table hadn’t occurred yet.

(And yes I decided to add a Duhhhh category to my blog postings.)

Posted by Tony | with no comments
Filed under: ,

Arrgggh, but there’s no code behind the Form’s Open event. I’ve triple checked.

Why is Access telling me there’s an error in this forms Open event when there’s no code in there?  I even threw in a msgbox in the Open event and it still comes up with the error message after the msgbox.  Arrrggghhhh.

Frigging computers.

Oh wait, umm, maybe I moved the code from the Open to the Load event and forgot to change the constants in the error handling lines of code created by MZTools.

Oops.  My fault.  I’m an idiot. Wasted three or four minutes.

Posted by Tony | with no comments
Filed under: ,

Backup of SQL Server databases from within Microsoft Access

WARNING:  Some of the following instructions may not be best practice.    This is a personal database so I can afford to take some shortcuts and not do thorough research.  If you do use these tips and sample code in production check back in a week and a month to see if there are any changes or comments.

Objective

I wanted to create a method of backing up a personal SQL Server database from within Access.   In a production environment you’d have tasks which ran on a regular basis, i.e. at midnight or whatever, that would do this.  But here I might update some records every few days and wanted to do this on my schedule.

Note that, as the names of the stored procedures indicate, I will be modifying these as I add more functionality such as database checks, log truncation, etc.

General SQL Server setup tips

I chose to create a new folder on the C drive of my SQL Server OS called SQL Server Files to store the files.  No good reason to do so because the master and other SQL Server databases are stored elsewhere but I figured what the heck.    From within SQL Server Management Studio Object Explorer right click on the Server node which is the top most node.   Then choose Properties and the Database Settings tab.   Then change the Database Default Locations as desired.

Just for grins and giggles I decided to change the port number that SQL Server uses.  I used the SQL Server Configuration Manager to update the TCP/IP port.   Note that this is not a good means of securing SQL Server. That is you have to go through through all the other security measures too.

Backup Stored Procedure (SP)

As I was unable to execute the SQL Server backup code directly within Access VBA I created the following stored procedure (SP) which I placed in a Utilities database in SQL Server. 

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[BackupAndMaintenance]
    @DatabaseName nvarchar(255),
    @FileName nvarchar(255)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

BACKUP DATABASE @DatabaseName
    TO DISK = @fileName
    WITH NAME = 'Full Backup';
END

To copy and paste the above into SQL Server Management Studio 2012 connect to the database and in the Object Explorer expand your master database items >> Programmability >> Stored Procedures and click on New Stored Procedure.    Then change the above code by changing ALTER to CREATE.   Click the red ! Execute icon to execute the T-SQL code which will create the stored procedure (SP).   Close the SP window.   Hit F5 to refresh the list of Stored Procedures on the Object Explorer.  Then open the SP by right clicking on the SP and click on Modify.  You will now see the CREATE has been changed to ALTER.

I chose to create these SPs in the master database as they will be used to backup other databases

Note that when you close SPs you will get a warning prompt very similar to the following:

Save changes to the following items?
SQLQuery10.sql.

You can ignore all such messages for SPs only because, by executing the SP wrapper code, you are actually altering the SP in the SQL Server database.  Do *NOT* ignore these warning messages for other objects such as Tables or Views.  I can remember to ignore these because they have non meaningful name.

I named this SP BackupAndMaintenance but I might change that later as I might want to put the maintenance functions in their own SP run by another account.   I’m going to think about that one a bit.

Creating the backup login/account

Expand the Security item in the Object Explorer and create a new Login called whatever you want but I chose backup. I used SQL Server authentication and used KeePass to store the userid and generate and store the password. (I’ve been using KeePass for a number of years to store my userids and generate random passwords for all my accounts. For most websites it will, if desired, automatically fill in the user name and account for you when you hit Ctrl+Alt+A. )

Then you need to add the backup login as having backup privileges to each of the databases.  Ignore the logical sounding Server Roles page on the Login Properties page. Instead go to the User Mapping page, click on each of the databases you wish to backup, including master, model and msdb and click on db_backupoperator.

There was a note somewhere about needing additional privileges if you want to verify the backup but I’ll leave that for another day.

And now you have an account which can only do backup and nothing else.

Granting the backup login/account permissions to the backup stored procedures.

At this point the backup login/account can’t actually execute the stored procedures.  It can only do backups.  So we need to explicitly add the backup account to the SPs with execute privileges.

Right click on the backup SPs, click on Properties and select the Permissions tab on the left hand side.   Click on the Search… command button and enter backup in the Object Names box.  Click on Ok to return to the SP Permissions screen and click the Grant Execute check box.

backup permissions

If you get the following message

-2147467259 - Microsoft OLE DB Provider for SQL Server
Cannot open database "Utilities" requested by the login. The login failed.

then you forgot this step.   Ask me how I know.

Even worse maybe you missed an ‘i’ or a ‘t’ in the Utilities database name when you created it in SQL Server Management Studio but you spelled it properly in the VBA code because the VBA code window has a larger font.   Rather frustrating figuring that one out.    Time for a visit to the optometrist.

The key here to figuring out this last problem was to use the SA userid and password to run the backup SP.    When that failed I was pretty sure the problem was not in my permissions but elsewhere.

VBA code within Access

Within a new Access database file I created some ADODB code to execute the SP.

Global Const ConnectString As String = "Provider=SQLOLEDB;data Source=<system name>\<instance name>,<optional port number>;" & _
    "Initial Catalog=<database name>;" & _
    "Encrypt=Yes;DataTypeCompatibility=80;"
Global Const BackupUserIDPwd As String = "User ID=backup;Password=<I’m not that stupid.  Usually.>"
Global Const strSQLServerLocalBackupPath As String = "X:\SQL Server Backup Files\"

Sub RunBackupSP(BackupPathAndFileName As String)

Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim cmd As New ADODB.Command
Dim strPathAndFileName As String, strDateTime As String

On Error GoTo tagError

     con.Open ConnectString & BackupUserIDPwd
     cmd.ActiveConnection = con
     cmd.CommandType = adCmdStoredProc
     cmd.CommandText = "BackupAndMaintenance"
     cmd.Parameters.Append cmd.CreateParameter("@DatabaseName", adVarChar, adParamInput, 255, gblDatabaseName)
     cmd.Parameters.Append cmd.CreateParameter("@FileName", adVarChar, adParamInput, 255, BackupPathAndFileName)
    
     Set rs = cmd.Execute()
   
    Exit Sub
    
tagError:
    Dim errLoop As ADODB.Error, i As Long, strTmp As String
      Dim strError As String, errErrors As ADODB.Errors, vbErrorNbr As Long

      i = 1

   ' Process
    vbErrorNbr = Err.Number
    strTmp = strTmp & Str(Err.Number) & " - " & Err.Source
    strTmp = strTmp & vbCrLf & "   " & Err.Description

   ' Enumerate Errors collection and display properties of
   ' each Error object.
     Set errErrors = con.Errors
     For Each errLoop In errErrors
          With errLoop
            ' don't display duplicate error
            If vbErrorNbr <> .Number Then
                strTmp = strTmp & vbCrLf & "Error #" & i & ":"
                strTmp = strTmp & vbCrLf & "   ADO Error   #" & .Number
                strTmp = strTmp & vbCrLf & "   Description  " & .Description
                strTmp = strTmp & vbCrLf & "   Source       " & .Source
                i = i + 1
            End If
       End With
    Next

      MsgBox strTmp

End Sub

Notes:

- I used the Microsoft ActiveX Data Objects 2.8 library as the ADO reference as that is the most recent ADO library which will work on Windows XP as per my blog article I've never quite trusted ADO because …

- The above error handling code will display all the nested ADO/ODBC errors.  Which is also why I put the SP in it’s own subroutine so the error handling routine wouldn’t be so ugly elsewhere.

- The path that you use must be a hard drive local to the SQL Server OS and can’t be a network path as the Windows account which is used to run the SQL Server service does not have any network privileges.

- When you run the backup yourself using SQL Server Management Studio you will only see the local hard drives, or tape devices, available on that system and not your hard drives.  It’s a bit confusing at first but makes some sense once you think about it and reread the previous note.

- I chose to keep the code which creates the backup path and file name along with the embedded date time in Access VBA code as I figured I might as well keep all such logic in one place rather than having some in VBA and some in the SP.

 

Further refinements

I chose to update a single record table in the database with the backup progress so should I restore the database elsewhere I have an internal record of the backup date and time.   There was a different datetime field for each of the three phases of the backup.   Hmm, now that I look at that the fields aren’t named all that well.  Oh well, I’ll change them tomorrow.

backup status table

I created a status textbox on my main backup program menu so I could see it working.

backup screen

From my standard development system I used some VBA code to copy the .bak file created to my local hard drive for daily backup purposes and also copy the file to my NAS (Network Attached Storage) device.    Now the path visualizing of the file gets a bit strange because the backup SP which runs on the SQL Server system only knows about local hard drives.   But then the VBA code running on my development system now needs to see that networked hard drive backup file from the perspective of the machine executing the file copy VBA code.    

I then run an API ShellExecute against the above three network shares and paths.  Again from the perspective of my development system and not the perspective of my SQL Server OS.   I only want to keep the latest copy of the backup file on my local hard drive which is the Q partition you see above.    So by running Windows Explorer I can easily see any old backup files and delete them as required.   I also only want to keep some of the backups on my NAS but not necessarily all of them.

I then created one SP that did a backup for the Master, Model and msdb databases again with date and time as part of the backup file name.   Among other things this will backup the backup login and it’s permissions I just created.

Maybe I’ll create a folder named by date and time and place all these backup files within that folder but that’s for another day.

Posted by Tony | with no comments

SQL Server utility–sp_Blitz

I’ve been doing some work lately in SQL Server.   I mentioned some issues I was having to my fellow Access MVPs and got some tips.   Former Access MVP Tom Wickerath came across an excellent stored procedure that does a large number of checks of your SQL Server environment.

sp_BLITZ™ – SQL Server Takeover Script

Here’s the blog entry with the latest release details – sp_Blitz v16: Snapshots, Recompiles, ShrinkDB, and More

As I go through the items mentioned one by one I’ll do my best to document the details I came across.

Posted by Tony | with no comments
Filed under: ,

Be aware of "Privacy Manager for HP Protect Tools"

A client of a fellow Access MVP was having  "Too many databases open" errors.  

Several users reported that Access was hanging.  AppHangB1 Access

That thread in turn referenced Access 2007 hangs/stops responding

Removing  Privacy Manager for HP Protect Tools solved these problems.

Posted by Tony | with no comments
Filed under: ,

The Auto FE Updater works just fine under Windows 8.

The Auto FE Updater works just fine under Windows 8.  

Now there will likely be issues if Access version next runs on the ARM CPU for tablets and other mobile devices.   But there is lots of time to figure out that solution and I have a plan.

Posted by Tony | with no comments

Auto FE Updater V3.20–Uncompress zip files including subfolders

Version 3.20 of the Auto FE Updater is now available for download.

The FAQ page was updated with a few items as well.

Posted by Tony | 2 comment(s)
Filed under:

Access 2010/Windows 7 performance hotfix

Description of the Access 2010 hotfix package (Ace-x-none.msp): August 30, 2011 This applies to Windows 7 and Windows Server 2008 R2 systems.

Apparently this solves the Access 2010 performance problem when it comes to ACE but not Jet 4.0 performance problems.

Posted by Tony | 1 comment(s)
Filed under: , , ,

Auto FE Updater works with Terminal Services RemoteApp

Details on configuration with the Auto FE Updater can be found at the Terminal Server RemoteApp page.

Thanks to Nick H of the U.K. for asking about this functionality.

Posted by Tony | with no comments
Filed under:

A new version of the Auto FE Updater is available–3.19

Version 3.19 - 2011-08-24  (674 kb, 21,462 lines of code)

  • Enterprise Edition can now create emails for all active users who have ever used the configuration file system.
  • I realized the form showing all users active in the backend and who tried to get into the locked configuration file was technically accurate but very user unfriendly.  So rather than showing just network ids it is now showing the user name and contact information.
  • Minor bug fixes

Now I have to admit that middle point is rather dumb on my part.  After all what use is just the userid when I have the user name and contact details present in the database.    It only took me a few minutes to add the fields to the query and thus to the form.  Oh well.

Posted by Tony | with no comments
Filed under:

Auto FE Updater Version 3.18 is now available for download

Version 3.18 - 2011-08-19  (706 kb, 21,239 lines of code)

  • Enterprise Edition can now create emails for all users currently in database or for all users who have tried to use the database while locked out.    
  • Error message screens can now create, but not automatically send,  emails containing the error message text to the support email address as defined in the Master screen.    Master users can now create, but not automatically send, that error message directly to Tony at Auto FE Updater support.   
  • Users will now get reminder screen after using the Auto FE Updater when the 14 day trial period has expired.   You can immediately then get a 7 day grace period to ask for and receive a trial license.
  • Remove Lock All toolbar button as I figure no one is likely using it.  If this is a problem let me know and I'll put it back
  • Minor bug fixes

Also see the version history page.

One of the biggest problems I have is feedback.  I simply don’t get much in the way of error messages and such.  So now when you the developer, but never the user, gets an error message you have the option of emailing me the message.  I hope this means I will get much more feedback as to the problems folks are encountering.

This also means I will likely be added web pages for specific commonly encountered errors and updating the FAQ pages.  But most importantly I can respond faster to problems being encountered.

Posted by Tony | with no comments
Filed under:

Access 2010 Compact & Repair breaks autonumber seed if index is descending

While this is very unusual having more than 1000 records in an Access 2010 MDB with the autonumber index in descending sequence a compact and repair loses the seed and the next record inserted fails.

Note this is the Microsoft partner forums so if you haven’t registered as a partner you won't see this.

http://social.microsoft.com/Forums/en-US/partnerofficeaccess/thread/9dc92ff4-c5a5-47c5-ad8c-9590d3eb8e69

I have reproduced this behavior myself.

(I sure would like to know why 1000 records is required to repro this though.  <smile>)

This behavior also happened in Jet 4.0 for a while.  AutoNumber field duplicates previous values after you compact and repair a database

Posted by Tony | 4 comment(s)
Filed under: , , ,

USB cable tips

I found retractable cables for most of my electronic devices for $3 or $5 including shipping on eBay. So now I don't have to drag along the meter long cables in the laptop bag. (That's 3 feet for my metrically challenged American friends.) While I
found a connector for my 5 year old Palm I couldn't find one for the proprietary end of my new Nikon compact camera! Shame on you Nikon for using a proprietary end with the standard USB micro connector likely would’ve worked.   Grrrr.

Of course I’ll probably still drag along my cables but I’ll put them in a Ziplock bag in my luggage.   It would really irritate me if one of those retractable cables went bad and I had to spend $20 or $30 on an overpriced retail cable.

You can also purchase adapters to go from one size to another for a few dollars.  I thought about those but then saw the retractable cables so decided to buy those instead.  For no particularly good reason.  

I put white finger nail polish on the "up" end of the black USB cable ends.   Frequently I have trouble seeing or feeling which end is “up”.  

Posted by Tony | with no comments

Did you know that you can change the PCs date and time from VBA code?

I didn’t.  Until I read The Daily WTF article Trans-Atlantic Time Trap.    There’s a link leading to a 2004 thread on this topic Change System Date via VBA.  Glad to see that fellow Access MVP Truitt B got bored one Saturday   Note that one poster commented that if you used Date and Time as the names of fields in tables or controls on forms or reports you could have issues.

I tried just the following VBA code on my Windows 7 system and received a Permission Denied error message which is, in my opinion, quite reasonable.

date = #2012-01-01#

If I run Access as an administrator it does let me change the date.   (I very quickly changed it back.)

I then tried creating a control named Date on a form and then assigned it a string value. 

Date = “test”

I then got a Type MisMatch message.  Which makes sense once you realize what is happening.

Next I tried

me.Date = “text”

but this gave me an Invalid use of Me Keyword.   Which also makes sense too.   But very, very confusing to someone who doesn’t realize that these are reserved words.

Speaking of reserved words a friend was happily working on a timesheet system using a table called Union.  Which worked just fine for months until he had to create a union query using that table.

For the definitive list see Allen Browne’s Problem names and reserved words in Access.

Posted by Tony | with no comments
Filed under: , , ,

Installing the 64 bit edition of Access Database Engine 2010 when the 32 bit edition is installed

You can indeed install the 64 bit edition of the Access Database Engine 2010 when the 32 bit edition is installed.    You need to add a /passive switch and install it from the command line.   See the Microsoft Access Database Engine 2010 Redistributable blog posting for more details.

Now who was the original discoverer of this quirk I have no idea.  I couldn’t find any mention of this on the MS website but …

Thanks to Sameer Panse in the Should Access Database Engine match OS install or Office install? posting for finding this option.

Posted by Tony | 2 comment(s)
Filed under: ,

Output to PDF - Run-Time error 2501: The OutputTo action was canceled

Turns out the problem was “an invalid character in the file name. “

Thanks to Septimus for raising the issue OutputTo DPF Error and figuring out the problem.

Posted by Tony | with no comments
Filed under: ,

ADO error 3251– Object or provider is not capable of performing requested operation.

If you are getting the above error message check the length of the path of the Access database.   A client had this problem where the path and Access database file name was “only” 181 characters.  Testing shows that the length of the path and the Access database file must be under about 128 characters.  Bizarre.

Posted by Tony | 2 comment(s)
Filed under: ,

Several VBA coding tricks

An interesting question was asked. How to make the following code simpler with Arrays   Now the poster was asking about arrays which I felt was going in the wrong direction so I replied with the “tricks” I use.

Posted by Tony | 2 comment(s)
Filed under: , ,

Auto FE Updater – now on YouTube

An introductory video on the Auto FE Updater is now on YouTube - Access Utilities: Tony's Auto FE Updater

I’m very grateful to Clif McIrvin and fellow Access MVP Crystal Long for spending the time.

Posted by Tony | 3 comment(s)
Filed under:
More Posts Next page »