Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9

    Need help autofilling a new record from the previous record

    I have a split form in which its used to log the running conditions of a machine. We have many different formulas/products that we run on this machine and the Operators log the running parameters every 5,000 lbs thats fed on the machine. Every formula will have a different amount of records because it depends on how much the customer has ordered of that certain product. We assign a lot number to every formula that we run and i dont want the Operators to have to continue entering the lot number and formula over and over when their running the same product.
    So what i need help doing is creating a button that will run code that copys the lot number and formula from the previous record into the new record. I need to have a button on the form or even a message box that pops up when they click on the lot number or operator field and asks the Operator if their running the same product and want to copy the formula and lot number to the new record, when they start a new formula with a new lot number they will manually enter that information once and then use the button until the next formula. If it helps any, the Formula field doesnt have to be a combo box, it can go back to a text box if necessary. This is my first Access project and I really enjoy using it, but I'm new to it and new to using Access Vba. Thanks for the help in advance and i hope i explained it clearly.
    I have attached a screen shot of my split form, excuse the red marks covering up a company logo.


    Click image for larger version. 

Name:	untitled.jpg 
Views:	23 
Size:	129.5 KB 
ID:	9351

  2. #2
    rpeare is offline VIP
    Windows XP Access 2003
    Join Date
    Jul 2011
    Posts
    5,442
    Is all of your data on one table or are you using a normalized structure (i.e. a table with formulas that has a PK, the formula name and any constants associated with that formula.

    If you are using a table with a Primary Key (PK) that's an autonumber or some other item that gets incrementally larger or smaller it would be pretty easy to do find the most recent record and apply it to your current data entry field.

    The easiest way would be to create a query that look at the (I'm guessing here) Lot Number you are currently processing and find the most recent ( max([PrimaryKeyField]) ). Then create a second query that links this 'preliminary' query to your actual data through the lot number and most recent primary key value. Then when you want to copy data you just look up values from this 'most recent record' query.

    It's hard to give you anything more than that without some knowledge of the database structure (tables) itself. Is there any way you can provide a sample of the database with garbage data?

  3. #3
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    Quote Originally Posted by rpeare View Post
    Is all of your data on one table or are you using a normalized structure (i.e. a table with formulas that has a PK, the formula name and any constants associated with that formula.

    If you are using a table with a Primary Key (PK) that's an autonumber or some other item that gets incrementally larger or smaller it would be pretty easy to do find the most recent record and apply it to your current data entry field.

    The easiest way would be to create a query that look at the (I'm guessing here) Lot Number you are currently processing and find the most recent ( max([PrimaryKeyField]) ). Then create a second query that links this 'preliminary' query to your actual data through the lot number and most recent primary key value. Then when you want to copy data you just look up values from this 'most recent record' query.

    It's hard to give you anything more than that without some knowledge of the database structure (tables) itself. Is there any way you can provide a sample of the database with garbage data?

    I have multiple tables, im sure i didnt setup everything ideally since this is the first time I've used Access, but so far its working good for what its used for. I do have a table for Formulas, but none of my tables are using a Primary Key and maybe thats something i need to change. I have worked with Vba in Excel but never Access and it seems a lot different from the little bit I've researched.

    Cant i use something like the code that is posted here and have it work off a command button?
    http://allenbrowne.com/ser-24.html

    I will get a sample of my database to provide more knowledge of how I've set it up.
    Thanks

  4. #4
    rpeare is offline VIP
    Windows XP Access 2003
    Join Date
    Jul 2011
    Posts
    5,442
    Yes you could use that code, it's basically looking at the dataset that's running your form, moving to the last record and assuming that's the one you want to copy. I don't know how your form is operating so I can't tell you if that's the desired result. Alternately if you can devise a query that shows you the most recent record you can use this code without using the cloned recordset, instead inserting your own recordset definition, fairly easily. But that gets back to my original post, how do you tell which record is the most recent (the one you want to copy from) Is it strictly by date? or are there other factors in determining which is the most recent record?

    I guess the first option would be to try this code (I was going to suggest a similar method but not knowing the structure of your form/tables etc makes it more difficult) and see if you get the results you want. Be careful though and do thorough testing, it may give you the result you want one time but not consistently depending on how your form is constructed.

  5. #5
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    Quote Originally Posted by rpeare View Post
    Yes you could use that code, it's basically looking at the dataset that's running your form, moving to the last record and assuming that's the one you want to copy. I don't know how your form is operating so I can't tell you if that's the desired result. Alternately if you can devise a query that shows you the most recent record you can use this code without using the cloned recordset, instead inserting your own recordset definition, fairly easily. But that gets back to my original post, how do you tell which record is the most recent (the one you want to copy from) Is it strictly by date? or are there other factors in determining which is the most recent record?

    I guess the first option would be to try this code (I was going to suggest a similar method but not knowing the structure of your form/tables etc makes it more difficult) and see if you get the results you want. Be careful though and do thorough testing, it may give you the result you want one time but not consistently depending on how your form is constructed.
    The records will never be re-sorted or filtered, they're in order by date (a-z) and the last record will always be the record I’m looking to copy from.
    The attachment in my first post is the main form and the only form where this data is entered, I have a very basic database, I don’t have any complicated relationships or sub forms, they use the form to enter data and run reports to view the past data to see how certain formulas ran.
    The form is filled out in the correct order by the user, they enter a record with the current machine conditions and then when it’s time to record the conditions again, they click on “New Record” on the top of my form.

    Since a new record is blank until the first keystoke, I believe I need to auto fill before any keystrokes are made in the date field. I would like to see something like this and I think this will work, but then again I’m the one asking for the help here, so what do I know.

    Date Field- when the user clicks on this field a message box pops up saying “Are you running the same formula?”
    If yes, the lot number field and formula field will automatically be auto filled from the last record.
    If no, End Sub.

    Now only if it was that easy to write the in VB....

  6. #6
    rpeare is offline VIP
    Windows XP Access 2003
    Join Date
    Jul 2011
    Posts
    5,442
    The code you linked before will do what you're asking with the exception that the data you want will fill in as soon as the first keystroke. You really do not want data to be entered before the first keystroke otherwise you're going to end up with a bunch of blank records. The code that you linked before is intended to copy *everything* from one record to the next so if you want to select a subset of those items you'll have to modify the code to pull out only what you want using something like FieldName = rst.fields("TableFieldName") rather than a blanket look for a control and fill it with data.

  7. #7
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    Quote Originally Posted by rpeare View Post
    The code you linked before will do what you're asking with the exception that the data you want will fill in as soon as the first keystroke. You really do not want data to be entered before the first keystroke otherwise you're going to end up with a bunch of blank records. The code that you linked before is intended to copy *everything* from one record to the next so if you want to select a subset of those items you'll have to modify the code to pull out only what you want using something like FieldName = rst.fields("TableFieldName") rather than a blanket look for a control and fill it with data.

    I tried the codes listed below and just tried to copy everything from last record into new record but i kept getting an error message when i tried running it stating "Object doesnt support this property or method" I have no clue what that means or how to get this to autofill like i want or anyway for that matter. Even if i was to get this code to work, i need a way for the user to be able to autofill sometimes NOT on every new record. I'm familiar with Excel Vba but I'm lost when it comes to Access Vba

    I'm really looking for help on getting this working....

    Private Sub Form_BeforeInsert(Cancel As Integer)
    Dim strMsg As String
    Call CarryOver(Me, strMsg)
    If strMsg <> vbNullString Then
    MsgBox strMsg, vbInformation
    End If
    End Sub



    Public Function CarryOver(frm As Form, strErrMsg As String, ParamArray avarExceptionList()) As Long
    On Error GoTo Err_Handler
    'Purpose: Carry over the same fields to a new record, based on the last record in the form.
    'Arguments: frm = the form to copy the values on.
    ' strErrMsg = string to append error messages to.
    ' avarExceptionList = list of control names NOT to copy values over to.
    'Return: Count of controls that had a value assigned.
    'Usage: In a form's BeforeInsert event, excluding Surname and City controls:
    ' Call CarryOver(Me, strMsg)

    Dim rs As DAO.Recordset 'Clone of form.
    Dim ctl As Control 'Each control on form.
    Dim strForm As String 'Name of form (for error handler.)
    Dim strControl As String 'Each control in the loop
    Dim strActiveControl As String 'Name of the active control. Don't assign this as user is typing in it.
    Dim strControlSource As String 'ControlSource property.
    Dim lngI As Long 'Loop counter.
    Dim lngLBound As Long 'Lower bound of exception list array.
    Dim lngUBound As Long 'Upper bound of exception list array.
    Dim bCancel As Boolean 'Flag to cancel this operation.
    Dim bSkip As Boolean 'Flag to skip one control.
    Dim lngKt As Long 'Count of controls assigned.

    'Initialize.
    strForm = frm.Name
    strActiveControl = frm.ActiveControl.Name
    lngLBound = LBound(avarExceptionList)
    lngUBound = UBound(avarExceptionList)

    'Must not assign values to the form's controls if it is not at a new record.
    If Not frm.NewRecord Then
    bCancel = True
    strErrMsg = strErrMsg & "Cannot carry values over. Form '" & strForm & "' is not at a new record." & vbCrLf
    End If
    'Find the record to copy, checking there is one.
    If Not bCancel Then
    Set rs = frm.RecordsetClone
    If rs.RecordCount <= 0& Then
    bCancel = True
    strErrMsg = strErrMsg & "Cannot carry values over. Form '" & strForm & "' has no recrods." & vbCrLf
    End If
    End If

    If Not bCancel Then
    'The last record in the form is the one to copy.
    rs.MoveLast
    'Loop the controls.
    For Each ctl In frm.Controls
    bSkip = False
    strControl = ctl.Name
    'Ignore the active control, those without a ControlSource, and those in the exception list.
    If (strControl <> strActiveControl) And HasProperty(ctl, "ControlSource") Then
    For lngI = lngLBound To lngUBound
    If avarExceptionList(lngI) = strControl Then
    bSkip = True
    Exit For
    End If
    Next
    If Not bSkip Then
    'Examine what this control is bound to. Ignore unbound, or bound to an expression.
    strControlSource = ctl.ControlSource
    If (strControlSource <> vbNullString) And Not (strControlSource Like "=*") Then
    'Ignore calculated fields (no SourceTable), autonumber fields, and null values.
    With rs(strControlSource)
    If (.SourceTable <> vbNullString) And ((.Attributes And dbAutoIncrField) = 0&) _
    And Not (IsCalcTableField(rs(strControlSource)) Or IsNull(.Value)) Then
    If ctl.Value = .Value Then
    'do nothing. (Skipping this can cause Error 3331.)
    Else
    ctl.Value = .Value
    lngKt = lngKt + 1&
    End If
    End If
    End With
    End If
    End If
    End If
    Next
    End If

    CarryOver = lngKt

    Exit_Handler:
    Set rs = Nothing
    Exit Function

    Err_Handler:
    strErrMsg = strErrMsg & Err.Description & vbCrLf
    Resume Exit_Handler
    End Function

    Private Function IsCalcTableField(fld As DAO.Field) As Boolean
    'Purpose: Returns True if fld is a calculated field (Access 2010 and later only.)
    On Error GoTo ExitHandler
    Dim strExpr As String

    strExpr = fld.Properties("Expression")
    If strExpr <> vbNullString Then
    IsCalcTableField = True
    End If

    ExitHandler:
    End Function

    Public Function HasProperty(obj As Object, strPropName As String) As Boolean
    'Purpose: Return true if the object has the property.
    Dim varDummy As Variant

    On Error Resume Next
    varDummy = obj.Properties(strPropName)
    HasProperty = (Err.Number = 0)
    End Function

  8. #8
    rpeare is offline VIP
    Windows XP Access 2003
    Join Date
    Jul 2011
    Posts
    5,442
    Can you make a copy of your database, clear out any real data but put in some fake data, zip it up and upload it to this site, it would be easier to give you direction with the actual construction of your database/form.

  9. #9
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    Yes i can do that but it was created in Access 2010 and i cannot get it to open in 2007. What version of Access are you using?

  10. #10
    rpeare is offline VIP
    Windows XP Access 2003
    Join Date
    Jul 2011
    Posts
    5,442
    In access 2010 Hover over the windows button in the upper left corner, when the menu appears click "SAVE AS Access 2003 Database" I can look at 2007, but 2003 is easier.

  11. #11
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    Zipped Fake Database.zipLet me know if you need anymore info... Thanks again for all your help so far!

  12. #12
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    I was able to get this code to work... I have 2 command buttons, 1 that says "new record" and the other says "new record/same formula"
    When new record/same formula is clicked, it starts a new record with the lot # and Formula fields autofilled from the previous record.
    I'm still interested in your opinion when you have time to look over the database i sent you, even if you just have suggestions on how i can improve the way i set it up, or a better way to autofill.

    Private Sub Command242_Click()
    On Error GoTo Err_Command242_Click

    'Define variables to hold the info for each field to be updated
    Dim VarLot As String
    Dim VarFormula As String

    'Set the variable values to current field values
    VarLot = Forms![Running Conditions Log Form]!Lot
    VarFormula = Forms![Running Conditions Log Form]!Formula

    'Start a new record
    DoCmd.GoToRecord , , acNewRec

    'Input the variable into the field
    Forms![Running Conditions Log Form]!Lot = VarLot
    Forms![Running Conditions Log Form]!Formula = VarFormula

    Exit_Command242_Click:
    Exit Sub

    Err_Command242_Click:
    MsgBox Err.Description
    Resume Exit_Command242_Click

    End Sub

  13. #13
    rpeare is offline VIP
    Windows XP Access 2003
    Join Date
    Jul 2011
    Posts
    5,442
    Ok this is exactly what I was talking about, you do not have a unique key field that will help you identify the most recent record to copy data from. In essence any code you use is not necessarily going to give you the most recent record. You are lucky (based on this example) that the data is showing in the order you want. I would very, very, very strongly recommend you put in an autonumber field (at the very least) and use it as your primary key for the table [Running Conditions Log]. In the version of access you're using it should be as simple as adding a field named Log_ID with an autonumber property, when you open the table again all of your fields should be in the same order but now have a 'counter' to show you which is the most recent record.

    So here's what I did
    1. Put in an autonumber field and called it LOG_ID in your [Running Conditions Log]
    2. On the form [Running Conditions Log Form] I put a TAG property on all your data entry fields of "DE"
    3. Added a button with the label 'Copy Previous Record'

    Added this code to the button

    Code:
    Dim ctl As Control
    Dim lMaxRec As Long
    Dim db As database
    Dim rst As Recordset
    Dim sSQL As String
    Dim iCurrField
    
    Set db = CurrentDb
    
    lMaxRec = DMax("[Log_ID]", "[Running Conditions Log]") 'gets the most recent log_ID
    Debug.Print lMaxRec
    
    'This section of code builds a SQL statement to power the population of the data on the form
    sSQL = "SELECT "
    
    For Each ctl In Me.Controls
        If ctl.Tag = "DE" Then
            Debug.Print ctl.Name & "  " & ctl.ControlSource 'if your form changes this will help you design the query to get fields in the correct order
            sSQL = sSQL & "[" & ctl.ControlSource & "],"
        End If
    Next ctl
    
    sSQL = Left(sSQL, Len(sSQL) - 1) & " FROM [Running Conditions Log] WHERE (Log_ID = " & lMaxRec & ")"
    Set rst = db.OpenRecordset(sSQL) 'opens the sql statement as the recordset for populating data
    rst.MoveFirst
    iCurrField = 0
    For Each ctl In Me.Controls
        If ctl.Tag = "DE" Then
            ctl.Value = rst.Fields(iCurrField)
            iCurrField = iCurrField + 1
        End If
    Next ctl
    
    rst.Close
    Debug.Print sSQL
    Set db = Nothing
    A few notes here. You are going to have more and more problems as you progress with your development for a few reasons that you should correct now if you can.

    1. Don't ever use spaces in your database object names, it causes no end of trouble when programming, for instance when I constructed the SQL statement to drive the copy I had to insert [] marks around each field name, if you had named your fields with no spaces I could have done away with that and made the code shorter.
    2. Don't ever use special characters in object names (you've used ', #, (, ), and ? in the one table I looked at) ' is a text indicator, # is a date indicator etc. Please, please, please change your field names while you can!
    3. Always use a primary key, access has an autonumber field for that very reason, even if you think you'll never use it, put it in, it will save you a ton of headaches.

    Now for some other important notes. The method I'm using assumes you want to copy every single field from the previous record. If that's not the case you ONLY set the tag of the fields you want to copy to "DE" and remove the tag from the fields you do not want to copy. The code I gave you is intended to work dynamically, so in case your data fields change this code will continue to work without any maintenance. This code will ONLY work if you are pulling data from 1 table, if you start linking other tables the SQL statement builder will have to be modified to handle that. Additionally when you use the method I've used for cycling through controls on your form Access does not allow you to alter the order in which they are processed so you have to build your query to show fields in the same order the controls are ordered, I've left a debug.print statement in there to show you the name of the control and the control source of that control in the order the form cycles through them. You'll notice if you look at the result after you click the 'copy previous record' button they appear in the immediate window of your code box.

    I also had to add a reference and change a reference (when you convert to a prior version access doesn't do it for you)

    I'm using Microsoft Office 12.0 Object Library and Microsoft DAO 3.6 Object Library.

    You'll have to find the replacement references in your version of access to accomodate this code.

    Here's a copy of your database with a functioning 'copy button'

    Fake Database-modified.zip

  14. #14
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    Wow! I cant thank you enough. Thanks for helping me out and all the time you spent looking over my data. I plan on fixing the issues you mentioned above and will let you know how it goes once I implement everything.
    Thanks again!

  15. #15
    sscott0203 is offline Novice
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2012
    Posts
    9
    I renamed all my tables, added a Primary Key/Autonumber on each table and cleaned up some other stuff. I was able to get the code you provided working without any problems at all, thanks again!
    I have searched for the last hour or two trying to find a way to add a message box to the onclick event of the Lot Number field, the message box would be a simple yes/no that would ask the user if they're running the same formula.
    If yes, you code would be called to run
    If no, end sub.
    If this is possible could you help me out one more time please

Page 1 of 2 12 LastLast
Please reply to this thread with any new information or opinions.

Similar Threads

  1. Replies: 8
    Last Post: 07-06-2013, 05:13 PM
  2. Replies: 22
    Last Post: 06-12-2012, 10:02 PM
  3. Autofilling when New Record Created from Form
    By SpdRacerX in forum Forms
    Replies: 6
    Last Post: 01-24-2012, 10:24 AM
  4. Replies: 3
    Last Post: 11-23-2011, 12:25 AM
  5. Replies: 1
    Last Post: 07-25-2011, 09:41 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums