Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Access97 and Custom counters

Posted on 1998-12-27
7
Medium Priority
?
311 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 400 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
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

 
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

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Access custom database properties are useful for storing miscellaneous bits of information in a format that persists through database closing and reopening.  This article shows how to create and use them.
Instead of error trapping or hard-coding for non-updateable fields when using QODBC, let VBA automatically disable them when forms open. This way, users can view but not change the data. Part 1 explained how to use schema tables to do this. Part 2 h…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

610 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