0

This is what I'm trying to do: I need to consolidate weekly forecasting excel templates from many different groups at work. I have created a form for them to fill out with all of their forecasting items / variances to plan / explanations. At that point I have a button on the excel template that places all of the data into a regular uniform table line by line beside the form. What I'd like to happen is after everything is in the uniform excel table that they click another button and using an ODBC connection to my access database make it append the data to a table in access for me? I have heard of this being done before but I'm not sure how.

I start by trying in excel by going to "From Other Sources" under the Data tab and clicking "From Microsoft Query" and then going through the steps of selecting my access database as the data source and then going through those steps until I get to a button I click that says "View data or edit query in Microsoft Query" but then I get lost how to use that to append data from the excel sheet to the access database using the ODBC connection.

Could anyone please help me figure out how to do this? There will be multiple groups appending to this access database from the excel template. Access will be an easy way for me to keep track of all of the data if I can do this.

Thanks!

Community
  • 1
  • 1
tortofe01
  • 51
  • 1
  • 8
  • Would it be possible to have the users do their data entry into an Access form instead of an Excel userform? – HansUp Feb 22 '16 at 14:40
  • @HansUp With many groups not having access to the same file paths it seems harder to distribute out an access database versus an excel file. This would also potentially allow multiple people to more easily write data to the database. Currently I make them copy and paste the data into a linked "List" on sharepoint to the access database, but it's not very good way. – tortofe01 Feb 22 '16 at 16:02

2 Answers2

0

Use an ADO connection (see connectionstrings.com). The steps are:

  1. Set a reference in your project to Microsoft ActiveX Data Objects 6.1 Library (or whatever version you have).

  2. Dim cn As ADODB.Connection

  3. Open the connection (a Google search will show you how)

  4. Load the values in your Excel sheet into an array

  5. Loop through the array and insert each record into the table. For example:

cn.Execute "INSERT INTO SomeTable VALUES (" & array(i,1) & "," & array(i,2) &...

The above is just a guide and may not be exactly right syntactically.

Edit:

Dim conString as String

conString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myFolder\myAccessFile.accdb; Persist Security Info=False;"

Set cn = New ADODB.Connection cn.Open conString

Excel Developers
  • 2,785
  • 2
  • 21
  • 35
  • I like the idea, could you give me a more specific link to look up some of this information maybe? A lot of this looks new to me and I've been combing through connectionstrings.com trying to find something relevant. But I don't exactly know what would be relevant lol. I have been reading the get to know connection strings and such but what after that would be good? – tortofe01 Feb 22 '16 at 16:04
  • There are many options. I added some code above. If you need more help here is a promising example: http://stackoverflow.com/questions/16161865/using-excel-vba-to-export-data-to-ms-access-table – Excel Developers Feb 22 '16 at 21:14
  • Thank you very much! I figured out a way to do it and I'll paste it in here in a few moments! You gave me the idea and then I continued to research! Thank you! Now I'm trying to figure out how to make a searchable drop down box in excel in which I can also use some kind of data validation on it. – tortofe01 Feb 24 '16 at 15:47
  • I do have one more question though. Since my piece of code writes line by line, is there a way to make sure the full table gets imported before it writes? For example, if the first 2 lines of data are fine and it writes them, but then it gets to the next line and something is wrong with the data in some way and it does not write it, can we check the full thing of code before writing it so I don't get only a portion of the data? – tortofe01 Feb 24 '16 at 19:02
  • Yes. Set the LockType of the recordset to adLockBatchOptmistic, remove the .Update line in the For loop, and do rs.BatchUpdate after the For loop. – Excel Developers Feb 24 '16 at 19:16
  • Once I add rs.UpdateBatch right under loop and adlockbatchoptimistic instead of just adlockoptimistic and get rid of the .update line in the loop it works when there is only one item in the table. But once more than one line is in the table it throws an error saying "Number of rows pending changes exceeded the limit" any ideas? – tortofe01 Feb 25 '16 at 16:21
  • I actually figured out that I needed to also add rs.CursorLocation = AdUseClient right above rs.Open statement. However, my last problem is now its making every field required. The error message now is whatever field "cannot be a zero-length string" even though some fields will not be required and others will (even though I don't know how to make vba tell me which fields are required and others not be required). I just want it to be able to write blanks if a field is blank like it did before, possible? – tortofe01 Feb 25 '16 at 16:43
  • You either need to change your Access table fields so that they will accept zero-length strings, or you need to check each range value before assigning it to a field: if it is a zero length string then skip the field. – Excel Developers Feb 26 '16 at 10:50
  • Thanks for all of the help, I have ran into another problem I've been searching. I have two fields that are drop down boxes in excel. I need them to use these exact items that are in the drop down box before submitted. However right now, say they want to not use the form to submit the data and just copy and paste their own data into the side table which the button will then submit. If they do not get the wording exactly, it will not be of much use to me. I tried enforcing integrity for certain fields in access but that breaks the batching (it still submits partial data) – tortofe01 Feb 26 '16 at 15:08
  • Could you direct me in the right direction on trying to figure out some vba code for this by chance? I have two fields in my excel sheet that are like this and I have a list of the exact wording each field needs to be (the options they have for that field) to validate this before it submits? – tortofe01 Feb 26 '16 at 15:09
  • And actually when there is an error with the code (say because I set one of the zero lengths in excel to not allow zero lengths) and then I keep that field blank in excel before I submit while also having a few rows with all fields in it. Even with the batch it is still submitting the other 2 that have all of the data. I thought by batching it, it wouldn't submit any? Sorry to bother you so much and I appreciate the help. I added the new code in the answer. – tortofe01 Feb 26 '16 at 15:15
0

Here's the answer to the problem I had above with the help of the other people responding on here:

    Sub ADOFromExcelToAccess()
   ' exports data from the active worksheet to a table in an Access database
 ' this procedure must be edited before use
  Dim cn As ADODB.Connection, rs As ADODB.Recordset, r As Long
' connect to the Access database
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; " & _
    "Data Source=Path to the database;"
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "Forecast_Items", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table
r = 3 ' the start row in the worksheet
Do While Len(Range("Q" & r).Formula) > 0
' repeat until first empty cell in column A
    With rs
        .AddNew ' create a new record
        ' add values to each field in the record
        .Fields("UserName") = Range("O" & r).Value
        .Fields("Forecast_Date") = Range("P" & r).Value
        .Fields("Area") = Range("Q" & r).Value
        .Fields("Description_Item") = Range("R" & r).Value
        .Fields("Account") = Range("S" & r).Value
        .Fields("RRDD") = Range("T" & r).Value
        .Fields("CostCenter") = Range("U" & r).Value
        .Fields("Fleet") = Range("V" & r).Value
        .Fields("ForecastAmount") = Range("W" & r).Value
        .Fields("PlanAmount") = Range("X" & r).Value
        .Fields("VarianceForecast") = Range("Y" & r).Value
        .Fields("Explanation") = Range("Z" & r).Value

        ' add more fields if necessary...
        .Update ' stores the new record
    End With
    r = r + 1 ' next row
Loop
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing




    End Sub

The other code that I have that is supposed to batch all or none if there are errors is. However when an error does occur it is still writing the ones that went through successfully.

     Sub ADOFromExcelToAccess()

     If MsgBox("This Button Will Submit all Data in the Table to the Right & Clear the Table! Are you sure?", vbYesNo) = vbNo Then Exit Sub


     ' exports data from the active worksheet to a table in an Access database
    ' this procedure must be edited before use
    Dim cn As ADODB.Connection, rs As ADODB.Recordset, r As Long
' connect to the Access database
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; " & _
    "Data Source=Filepath.mdb;"
' open a recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open "Forecast_Items", cn, adOpenKeyset, adLockBatchOptimistic, adCmdTable
' all records in a table
r = 3 ' the start row in the worksheet
Do While Len(Range("Q" & r).Formula) > 0
' repeat until first empty cell in column A
    With rs
        .AddNew ' create a new record
        ' add values to each field in the record
        .Fields("UserName") = Range("O" & r).Value
        .Fields("Forecast_Date") = Range("P" & r).Value
        .Fields("Area") = Range("Q" & r).Value
        .Fields("Description_Item") = Range("R" & r).Value
        .Fields("Account") = Range("S" & r).Value
        .Fields("RRDD") = Range("T" & r).Value
        .Fields("CostCenter") = Range("U" & r).Value
        .Fields("Fleet") = Range("V" & r).Value
        .Fields("ForecastAmount") = Range("W" & r).Value
        .Fields("PlanAmount") = Range("X" & r).Value
        .Fields("VarianceForecast") = Range("Y" & r).Value
        .Fields("Explanation") = Range("Z" & r).Value



        ' add more fields if necessary...

    End With
    r = r + 1 ' next row
Loop
rs.UpdateBatch 'injects full table from excel into access at the same time, eliminating possible errors with inserting certain rows over others
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing

MsgBox ("Data was Submitted Successfully!")

Exit Sub




  End Sub
tortofe01
  • 51
  • 1
  • 8