在SQL / VBA中有效填写大量字段

时间:2016-10-18 16:04:13

标签: sql vba excel-vba excel

我正在使用一个包含大量字段(40+)的表,其中每个记录都有一些字段需要填充“自定义”数据(基于程序的结果),其余需要重复输入相同的“默认”值。我正在通过MS访问在VBA中编写此程序。

使用字段条目创建新记录的实际语法不是问题,但我不确定为所有这些默认条目输入最有效/可读代码的最佳方法。由于无法仅使用列位置引用SQL字段,因此我认为当通过人类可读的名称引用每个字段时,代码会很快变得难看。

我目前的代码是

 DoCmd.RunSQL "INSERT INTO Table1 ([PartNumber],[Description],[Alternate],[Supplier],[Location],[Rev]) values('" & PartNumber & "','" & Description & "'," _
                                & " '" & Alt & "', '" & Supplier & "', '" & Location & "','" & Rev & "')"

因此,如果超过35个以上,这将变得更加丑陋。

3 个答案:

答案 0 :(得分:1)

我也在寻找类似问题的答案,知道插入像你的例子真的是一个疯狂(和丑陋)的想法。我想出的是这样的事情:

Option Explicit

Public Sub GenerateDataIntoTable()

    Dim str_table_name      As String: str_table_name = "Main"
    Dim arr_column_names    As Variant
    Dim arr_values          As Variant

    ReDim arr_column_names(6)
    ReDim arr_values(6)

    arr_column_names(0) = "UserName"
    arr_column_names(1) = "CurrentDate"
    arr_column_names(2) = "CurrentTime"
    arr_column_names(3) = "CurrentLocation"
    arr_column_names(4) = "Status1"
    arr_column_names(5) = "Status2"
    arr_column_names(6) = "Status3"

    arr_values(0) = Environ("username")
    arr_values(1) = Date
    arr_values(2) = Time
    arr_values(3) = Application.ActiveWorkbook.FullName
    arr_values(4) = 2
    arr_values(5) = arr_values(4) + 4
    arr_values(6) = arr_values(5) - 4

    Debug.Print b_insert_into_table(str_table_name, arr_column_names, arr_values)

End Sub

Function b_insert_into_table(str_table_name As String, arr_column_names As Variant, arr_values As Variant) As Boolean

    Dim conn            As Object
    Dim str_order       As String

    Set conn = CreateObject("ADODB.Connection")
    'conn.Open str_connection_string

    str_order = "insert into dbo." & str_table_name
    str_order = str_order & str_generate_order(arr_column_names, arr_values)
    Debug.Print str_order
    'conn.Execute str_order
    'conn.Close
    Set conn = Nothing

    b_insert_into_table = True

End Function

Public Function str_generate_order(arr_column_names As Variant, arr_values As Variant) As String

    Dim l_counter       As Long
    Dim str_result      As String

    Dim str_left        As String: str_left = "('"
    Dim str_midd        As String: str_midd = "','"
    Dim str_right       As String: str_right = "')"

    str_result = "("
    For l_counter = LBound(arr_column_names) To UBound(arr_column_names)
        str_result = str_result & arr_column_names(l_counter) & ","
    Next l_counter

    str_result = Left(str_result, Len(str_result) - 1)
    str_result = str_result & ")"
    str_result = str_result & "values"

    str_result = str_result & str_left
    For l_counter = LBound(arr_values) To UBound(arr_values)
        str_result = str_result & arr_values(l_counter)

        If l_counter < UBound(arr_values) Then
            str_result = str_result & str_midd
        Else
            str_result = str_result & str_right
        End If

    Next l_counter

    str_generate_order = str_result

End Function

要运行它,请运行GenerateDataIntoTable()。如果要在应用程序中运行它,请取消注释b_insert_into_table中的注释,并为str_connection_string设置有意义的内容。

答案 1 :(得分:0)

考虑一个参数化查询,它是所有RDMS的编程行业最佳实践,您可以在其中准备初始SQL语句,然后根据数据类型将值绑定到声明的参数。通过这种方式,您可以避免使用所需的引号括起每个值,甚至可以在不重新分配查询语句的情况下进行迭代。最重要的是,您可以克服sql injection,因为恶意用户可以通过用户输入运行SQL查询,并对数据和/或架构造成严重损害。

在MS Access SQL中,您可以使用PARAMETERS子句定义命名参数。然后在VBA中,您可以为每个值分配值。此外,对于保存的查询,处理效率更高,因为引擎优化了查询,而不是在运行时作为新查询处理的VBA字符串查询。

SQL (在下面保存为存储的查询;添加所有40个字段)

PARAMETERS partparam INTEGER, descparam TEXT(255), altparam TEXT(255),
           supplierparam TEXT(255), locationparam TEXT(255), revparam TEXT(255);
INSERT INTO Table1 ([PartNumber],[Description],[Alternate], [Supplier],[Location],[Rev])
VALUES(partparam, descparam, altparam, supplierparam, locationparam, revparam);

VBA (引用存储的querydef并将值绑定到相应的命名参数)

Dim db as Database
Dim qdef as Querydef

Set db = CurrentDb    
Set qdef = db.QueryDefs("SavedQueryName")

qdef!partparam = 9999
qdef!descparam = "Some description"
qdef!altparam = "Some alternate"
qdef!supplierparam = "Some supplier"
qdef!locationparam = "Some location"
qdef!revparam = "Some rev"

qdef.Execute dbFailOnError

Set qdef = Nothing
Set db = Nothing

答案 2 :(得分:0)

像Parfait建议的那样。这样可以更加轻松地进行维护,调试等。另外,请参阅下面的示例。

Sub DAOFromExcelToAccess()
' exports data from the active worksheet to a table in an Access database
' this procedure must be edited before use
Dim db As Database, rs As Recordset, r As Long
    Set db = OpenDatabase("C:\FolderName\DataBaseName.mdb") 
    ' open the database
    Set rs = db.OpenRecordset("TableName", dbOpenTable) 
    ' get all records in a table
    r = 3 ' the start row in the worksheet
    Do While Len(Range("A" & 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("FieldName1") = Range("A" & r).Value
            .Fields("FieldName2") = Range("B" & r).Value
            .Fields("FieldNameN") = Range("C" & 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
    db.Close
    Set db = Nothing
End Sub

http://www.erlandsendata.no/english/index.php?d=envbadacexportado

或。 。 。

isinstance

http://www.erlandsendata.no/english/index.php?d=envbadacexportdao