Solved

Access97 and Custom counters

Posted on 1998-12-27
7
303 Views
Last Modified: 2012-05-04
I'm building a multi-user database with custom counter. (I have referenced KB article Q140908) Unlike their example, however, I cannot store the next number, since it uses the month (i.e., if the last number issued is 1998-12-101, the next number issued would be 1998-12-102 if issued this month or 1999-01-01 if issued next month.)

My problem comes when trying to find the last number issued. As suggested in the KB article, I use a separate table to store the last number instead next number.

With two computers on my desk, I've tried testing ways to allow one instance of the database to have exclusive access to this table while trying to get the other to one wait until the first one was done, but to no avail. (Using "On Error" to trap the 3260 error and looping until it went away. The only thing I've managed to do was to lock out neither or both intances at once!)

This is my first foray into multi user databases, basically working with bound forms up until now. Accessing tables with code instead of bound forms is my weak area, so I don't know if there is some sort of "exclusive" switch or option I'm missing on the
Set MyTable = MyDB.OpenRecordset("Counter Table")
statement, which Microsoft assumes you'll use or what.

Any leads (or answers) would be greatly apprectiated.
-Thanks
0
Comment
Question by:scottk122798
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 

Author Comment

by:scottk122798
ID: 1972152
Edited text of question
0
 
LVL 10

Accepted Solution

by:
brewdog earned 100 total points
ID: 1972153
It sounds like you need to do two things:
1.  Locate the last "counter" used and increment it appropriately
2.  Make sure that that counter number isn't taken twice (by different users)

Here's how I'd approach it . . .

    Dim rs As Recordset
    Dim strCounter As String
    Dim strLast As String
    Dim strNext As String
   
    Set rs = CurrentDb().OpenRecordset("tblCounter", , dbDenyRead)
               'this prevents other users from even reading the counter until I'm done
    strLast = rs(0)
    If Left$(strLast, 4) = Year(Date) Then
        strCounter = Left$(strLast, 4) & "-"
    Else
        strCounter = Year(Date) & "-"
    End If
   
    If Mid$(strLast, 6, 2) = Month(Date) Then
        strCounter = strCounter & Mid$(strLast, 6, 2) & "-"
       strNext = CInt(Right$(strLast, 3)) + 1
        Select Case Len(strNext)
            Case 1
                strCounter = strCounter & "00" & strNext
            Case 2
                strCounter = strCounter & "00" & strNext
            Case 3
                strCounter = strCounter & strNext
        End Select
    Else
        strCounter = strCounter & Month(Date) & "-001"
    End If
       
    txtCounter = strCounter
    rs.Edit
    rs(0) = strCounter
    rs.Update
    rs.Close

This will get your next counter value, updating the counter table at the same time. And with the table locked, even for read access, you should be able to avoid the same number being taken twice. You would, of course, need to error trap the routine to retry multiple times before giving up on getting the next autonumber.

I wasn't sure what you were going to do with the new counter number, so I put it into a text box on the form and then updated the counter table. You could modify that, obviously.

Is this what you were looking for?

brewdog
0
 

Author Comment

by:scottk122798
ID: 1972154
Thanks for your reply Brewdog, however, it didn't completely work!

Your method yielded better results than mine; my method never yielded different numbers. With your method, I only got duplicate numbers about every sixth time. (I have two PC's on my desk to test the worst case scenario.)

My original "On Error" tested for 3260 and on 3260 sent the user back to the "Set rs = CurrentDb().OpenRecordSet("tblLastNumber",,dbDenyRead)" statement because I assumed this statement is what would cause the error. (Any other error halts execution in the standard way.)  As a flag to show me who was waiting, I put a visible counter on the form, incremented by the waiting. No increment. Suspicious, I Then put a message box (the Most reliable indicator, I've found) before I even test for 3260. Duplicate number or not, the message box never comes up! So, as far as I can tell, the "On Error" portion never gets executed and the table isn't being opened exclusively.

Again, any help appreciated

P.S. Thanks for coding for a fact I left out (duh!). Year, Month and Sequence are three separate fields, not one. The only other change I made was to refer to the three fields as rs!intYear, rs!intMonth, etc. instead of rs(0), rs(1), etc.
0
Migrating Your Company's PCs

To keep pace with competitors, businesses must keep employees productive, and that means providing them with the latest technology. This document provides the tips and tricks you need to help you migrate an outdated PC fleet to new desktops, laptops, and tablets.

 
LVL 10

Expert Comment

by:brewdog
ID: 1972155
that's strange . . . I would think the DenyRead would take care of that . . .

All right, I just tested it on mine, and it worked fine (with two "users" at least):

Private Sub cmdCounter_Click()
    On Error GoTo CounterError

    rs.LockEdits = True

GetCounter:
    strLast = rs(0)
    If Left$(strLast, 4) = Year(Date) Then
        strCounter = Left$(strLast, 4) & "-"
    Else
        strCounter = Year(Date) & "-"
    End If
   
    Select Case Len(Month(Date))
        Case 1
            strMonth = "0" & Month(Date)
        Case 2
            strMonth = Month(Date)
    End Select

    If Mid$(strLast, 6, 2) = strMonth Then
        strCounter = strCounter & strMonth & "-"
       strNext = CInt(Right$(strLast, 3)) + 1
        Select Case Len(strNext)
            Case 1
                strCounter = strCounter & "00" & strNext
            Case 2
                strCounter = strCounter & "00" & strNext
            Case 3
                strCounter = strCounter & strNext
        End Select
    Else
    End If
       
    txtCounter = strCounter
    rs.Edit
    rs(0) = strCounter
    rs.Update
 Exit Sub
CounterError:
    Select Case Err.Number
        Case 3260
            Resume GetCounter
        Case Else
            MsgBox "Error " & Err.Number & ", " & Err.Description, vbInformation, "Unexpected"
            Exit Sub
    End Select
End Sub

The other things I did were to put the Dim statements at the general declarations level for the form (at least the recordset variable should be put there) and then set the recordset (without the DenyRead) at the Form_Load event. Like I said, it worked fine for me. Let me know if it works for you, too, Scott.

brewdog
0
 

Author Comment

by:scottk122798
ID: 1972156
Brewdog,
Apologies for not replying sooner. A staffing shortage made me 'popular.'
I hate to say it, but the new code worked worse! I could get a duplicate number almost everytime! By recoding it this way, I was able to get the duplications down to 50%:

Private Sub cmdGetNumber_Click()
On Error GoTo Err_cmdGetNumber_Click
    Dim rsLastCaseNumber As Recordset
    Dim intYearIn As Integer
    Dim intYearCurrent As Integer
    Dim intYearOut As Integer
    Dim intMonthIn As Integer
    Dim intMonthCurrent As Integer
    Dim intMonthOut As Integer
    Dim intSequenceIn As Integer
    Dim intSequenceOut As Integer
 
    Set rsLastCaseNumber = CurrentDb().OpenRecordset("tblLastCaseNumber", , dbDenyRead)
    'Set rsLastCaseNumber = CurrentDb().OpenRecordset("tblLastCaseNumber")
    rsLastCaseNumber.LockEdits = True
   
GetCounter:
    intYearIn = rsLastCaseNumber(0)
    intMonthIn = rsLastCaseNumber(1)
    intSequenceIn = rsLastCaseNumber(2)
   
    If intYearIn = Year(Date) Then
        If intMonthIn = Month(Date) Then
            intYearOut = Year(Date)
            intMonthOut = Month(Date)
            intSequenceOut = intSequenceIn + 1
        Else
            intYearOut = Year(Date)
            intMonthOut = Month(Date)
            intSequenceOut = 1
        End If
    Else
        intYearOut = Year(Date)
        intMonthOut = Month(Date)
        intSequenceOut = 1
    End If
   
    rsLastCaseNumber.Edit
    rsLastCaseNumber(0) = intYearOut
    rsLastCaseNumber(1) = intMonthOut
    rsLastCaseNumber(2) = intSequenceOut
    rsLastCaseNumber.Update
    rsLastCaseNumber.Close
    Me![txtYear] = intYearOut
    Me![txtMonth] = intMonthOut
    Me![txtSequence] = intSequenceOut


Exit_cmdGetNumber_Click:
    Exit Sub

Err_cmdGetNumber_Click:
    Select Case Err.Number
        Case 3260
            Resume GetCounter
        Case Else
            MsgBox "Error" & Err.Number & ", " & Err.Description, vbInformation, "Unexpected"
            Exit Sub
        End Select
End Sub

It seems as if making it redefine everytime and closing after execution helped. The oddity is that it's a perfect 50 ratio; duplicate, non-duplicate, duplicate, non-duplicate...
Since yours works with the code you supplied, I'm beginning to think it's a setting rather than code.
-Scott
0
 
LVL 10

Expert Comment

by:brewdog
ID: 1972157
So yours actually saved the duplicates? That's strange . . . don't suppose I could get a copy of your db (only the relevant parts) to test on my machine? I'm at dbrewer@uhc.com if you want to send one. I know both of us would like to be finished with this question! :)
0
 
LVL 1

Expert Comment

by:Moondancer
ID: 6875655
GREETINGS!

This question was awarded, but never cleared due to the JSP-500 errors of that time.  It was "stuck" against userID -1 versus the intended expert whom you awarded.  This corrects the problem and the expert will now receive these points; points verified.

Please click on your Member Profile and select "View Question History" to navigate through any open or locked questions you may have to update and finalize them.  If you are an EE Pro user, you can also choose Power Search to find all your open questions.

This is the Community Support link, if help is needed, along with the link to All Topics which reflects many TAs recently added.  Also in the Community Support link is a question on how experts can help, if they wish, on the cleaning of old and abandoned questions.

http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
http://www.experts-exchange.com/jsp/zonesAll.jsp
 
Thank you,
Moondancer
Moderator @ Experts Exchange
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I see at least one EE question a week that pertains to using temporary tables in MS Access.  But surprisingly, I was unable to find a single article devoted solely to this topic. I don’t intend to describe all of the uses of temporary tables in t…
It’s the first day of March, the weather is starting to warm up and the excitement of the upcoming St. Patrick’s Day holiday can be felt throughout the world.
In Microsoft Access, learn how to “cascade” or have the displayed data of one combo control depend upon what’s entered in another. Base the dependent combo on a query for its row source: Add a reference to the first combo on the form as criteria i…
Using Microsoft Access, learn some simple rules for how to construct tables in a relational database. Split up all multi-value fields into single values: Split up fields that belong to other things into separate tables: Make sure that all record…

733 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