用于从Excel更新/创建新记录以访问的VBA代码

用于从Excel更新/创建新记录以访问的VBA代码,excel,vba,ms-access,Excel,Vba,Ms Access,我一直在到处寻找答案,但我在VBA方面的基础较低的技能并不能帮助我理解我试图编写的代码 到目前为止,我有以下代码: 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.Recordse

我一直在到处寻找答案,但我在VBA方面的基础较低的技能并不能帮助我理解我试图编写的代码

到目前为止,我有以下代码:

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.ACE.OLEDB.12.0; " & _
    "Data Source=\\GSS_Model_2.4.accdb;"
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "Forecast_T", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table
For i = 4 To 16
    x = 0
    Do While Len(Range("E" & i).Offset(0, x).Formula) > 0
' repeat until first empty cell in column A
        With rs
            .AddNew ' create a new record
            .Fields("Products") = Range("C" & i).Value
            .Fields("Mapping") = Range("A1").Value
            .Fields("Region") = Range("B2").Value
            .Fields("ARPU") = Range("D" & i).Value
            .Fields("Quarter_F") = Range("E3").Offset(0, x).Value
            .Fields("Year_F") = Range("E2").Offset(0, x).Value
            .Fields("Units_F") = Range("E" & i).Offset(0, x).Value
            .Update
         ' stores the new record
    End With
    x = x + 1
    Loop
Next i
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
到目前为止,这段代码正是我想要的。我知道我想添加一个条目,根据4条规则检查记录是否存在:产品、地区、季度和年度 如果它与这些匹配,它应该更新其他字段(Units\u F,ARPU)。如果没有,它应该正确运行代码并创建新记录

你的帮助将非常感谢,我在这里被绊住了,不知道怎么出去


谢谢

写完这篇文章后,我才意识到你在使用VBA,所以我的答案不起作用。但是你应该能够了解发生了什么。不过,这是一个想法。对于VBA集合,请查看以下内容:


我有一个Excel电子表格,从单元格A1开始有以下数据

product  variety  price
bacon    regular  3.79
bacon    premium  4.89
bacon    deluxe   5.99
我的Access数据库中有一个名为“PriceList”的表,其中包含以下数据

product  variety  price
-------  -------  -----
bacon    premium  4.99
bacon    regular  3.99
以下Excel VBA将使用“普通”和“高级”的新价格更新现有访问记录,并在表中为“豪华”添加新行:

Public子UpdatePriceList()
Dim cn作为ADODB.Connection,rs作为ADODB.Recordset
Dim sProduct作为字符串,sVariety作为字符串,cPrice作为变体
'连接到Access数据库
Set cn=New ADODB.Connection
cn.Open“Provider=Microsoft.ACE.OLEDB.12.0;”_
“数据源=C:\Users\Gord\Desktop\Database1.accdb;”
'打开记录集
Set rs=New ADODB.Recordset
rs.开放式“价格表”、cn、adOpenKeyset、ADLOCKOPTIME、adCmdTable
范围(“A2”)。激活“第1行包含列标题
不为空时执行(ActiveCell)
sProduct=ActiveCell.Value
sVariety=ActiveCell.Offset(0,1).Value
cPrice=ActiveCell.Offset(0,2).Value
rs.Filter=“product=”&sProduct&“和variety=”&sVariety&“”
如果是rs.EOF那么
调试。打印“无现有记录-添加新记录…”
rs.Filter=“”
艾德纽卢比
rs(“产品”)。价值=产品
rs(“品种”)。价值=多样性
其他的
调试。打印“找到现有记录…”
如果结束
卢比(“价格”)。价值=cPrice
rs.更新
调试。打印“…记录更新完成。”
ActiveCell.Offset(1,0)。激活“下一个单元格”
环
rs.Close
设置rs=无
cn.Close
设置cn=Nothing
端接头

我没有足够的声誉对上述答案中的一个发表评论。这个解决方案非常好,但是如果您在一行中有大量记录要循环,那么将所有内容都包含在一个循环中就更容易了。我的数据也保存在Excel表格中(但如果您只有一个非动态范围,请将其作为一个范围输入)

就是这样-然后我关闭了数据库/连接等,并给我的用户一条消息说数据已经写入


这里您真正需要注意的是,我的userform(尚未)包含数据类型检查,但这是我的下一段代码。否则,当您打开Access时,您可能会从Access中获得异常或一些非常糟糕的数据

感谢您的回复,我理解您是如何做到这一点的,但我真的缺少在VBA中执行此操作所需的命令。。。如果有人知道,我也会很高兴听到你的消息。上次我检查LINQ时,它不能在VBA中使用
product  variety  price
-------  -------  -----
bacon    premium  4.99
bacon    regular  3.99
Set LO = wb.Worksheets("Sheet").ListObjects("YOUR TABLE NAME")
rg = LO.DataBodyRange
'All of the connection stuff from above that is excellent
For x = LBound(rg) To UBound(rg)

'Note that first I needed to find the row in my table containing the record to update
'And that I also got my user to enter all of the record info from a user form
'This will mostly work for you regardless, just get rid of the L/Ubound and search
'Your range for the row you will be working on

    If rg(x,1) = Me.cmbProject.Value Then
        working_row = x
        Exit For
    End If
Next
For i = 2 To 17 ' This would be specific to however long your table is, or another range
'argument would work just as well, I was a bit lazy here
    col_names(i-1) = LO.HeaderRowRange(i) 'Write the headers from table into an array
    Data(i-1) = Me.Controls("Textbox" & i).Value 'Get the data the user entered
Next i
'Filter the Access table to the row you will be entering the data for. I didn't need
'Error checking because users had to select a value from a combobox
rst.Filter = "[Column Name] ='" & "Value to filter on (for me the combobox val)"
For i = 1 To 16 'Again using a len(Data) would work vs. 16 hard code
    rst(col_names(i)).Value = Data(i)
Next i