【问题标题】:Import excel file return null for existing data导入excel文件对现有数据返回null
【发布时间】:2012-04-05 18:26:40
【问题描述】:

我正在尝试将 Excel 文件 Excel97-2003(仅限第一张工作表)导入 Access 数据库。为此,我正在使用以下代码:

Dim cnnExcel As New ADODB.Connection
Dim rsExcel As New ADODB.Recordset
With cnnExcel
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source=" & strFileSelected & ";" & "Extended Properties=Excel 8.0"
    .CursorLocation = adUseClient
    .Open
End With

rsExcel.Open "SELECT * FROM [Sheet1]", cnnExcel

excel文件中的所有列都是字符串,当你用Excel2003打开它时,类型为“General”(没有特殊格式),其他3列是日期。 我的问题是单元格中存在的值为空。例如,如果第一个值是字符串,而不是该列中有整数,则它将返回为空,反之亦然 有什么解决办法吗?

谢谢

【问题讨论】:

    标签: excel ms-access vba adodb recordset


    【解决方案1】:

    解决方案 1

    使用您的代码,我能够毫无问题地从 Excel 工作表中正确加载数据。
    但是,请检查您的 SQL 查询,它应该是这样的:

    rsExcel.Open "SELECT * FROM [Sheet 1$]", cnnExcel
    

    FROM部分的规则如下:

    • 查询整个工作表: SELECT * FROM [SheetName$],注意$
    • 从一个范围查询:
      SELECT * FROM [SheetName$A1:C5]
    • 从命名范围查询:
      SELECT * FROM NameRange
    • 从包含非字母数字字符的工作表中查询:
      SELECT * FROM ['This;is.My SheetName$']

    在我的机器上运行的代码:

    Dim cnnExcel As Object
    Dim rsExcel As Object
    Set cnnExcel = CreateObject("ADODB.Connection")
    Set rsExcel = CreateObject("ADODB.RecordSet")
    With cnnExcel
        .Provider = "Microsoft.Jet.OLEDB.4.0"
        .ConnectionString = "Data Source=D:\Query1.xls;Extended Properties=Excel 8.0"
        .CursorLocation = 3
        .Open
    End With
    
    rsExcel.Open "SELECT * FROM [Sheet 1$]", cnnExcel
    Debug.Print rsExcel.RecordCount '  Prints the number of rows containing data '
    Do
        Debug.Print "Col1: " & rsExcel.Fields(0) & "  - Col2: " & rsExcel.Fields(1)
        rsExcel.MoveNext
    Loop While Not rsExcel.EOF
    rsExcel.Close
    

    解决方案 2

    直接操作 Excel 工作簿可能会更好。
    假设您的 Access 数据库中有一个表 MyTable,您要在其中导入字段 myAmyBmyC(具有您期望的正确数据类型!) Excel 的内容 @987654333 @ 有对应的列。

    简化的 VBA 代码如下所示:

    Sub ImportData(fname As String)
        Dim xlo As Object
        Dim xlWb As Object
        Dim xlWs As Object
        Dim colA, colB, ColC As Variant
        Dim db As DAO.Database
        Dim rs As DAO.Recordset
        Dim thereIsData As Boolean
        Dim row As Integer
    
        ' Open Excel sheet, try to re-use Excel if it is open '
        On Error Resume Next
        Set xlo = GetObject("Excel.Application")
        If xlo Is Nothing Then Set xlo = CreateObject("Excel.Application")
        On Error Goto 0
        Set xlWb = xla.Workbooks.Open(fname)
        Set xlWs = xlWb.Worksheets(1)  ' Sheet 1'
    
        ' Open table where the results will be stored '
        Set db = CurrentDb()
        Set rs = db.OpenRecordset("MyTable", dbOpenDynaset)
        Do
           colA = xlWs.Cells(row, 1).Value
           colB = xlWs.Cells(row, 2).Value
           colC = xlWs.Cells(row, 3).Value
           ' We will stop at the first empty row '
           thereIsData = Not (IsBlank(colA) And IsBlank(colB) And IsBlank(colC))
           If thereIsData Then
                ' Add the Excel data to the table '
                rs.AddNew
                    rs!myA = colA
                    rs!myA = colB
                    rs!myA = colC
                rs.Update
           End If
           row = row + 1
        Loop While thereIsData
        rs.Close
        ' Cleanup '
        Set rs = Nothing
        Set db = Nothing
        Set xlWs = Nothing
        Set xlWb = Nothing
        xla.DisplayAlerts = False
        xla.Quit
        Set xls = Nothing
    End Sub
    
    '-----------------------------------------------------------------------------  
    ' True if the argument is Nothing, Null, Empty, Missing or an empty string .  
    '-----------------------------------------------------------------------------  
    Public Function IsBlank(arg As Variant) As Boolean  
        Select Case VarType(arg)  
            Case vbEmpty  
                IsBlank = True  
            Case vbNull  
                IsBlank = True  
            Case vbString  
                IsBlank = (arg = vbNullString)  
            Case vbObject  
                IsBlank = (arg Is Nothing)  
            Case Else  
                IsBlank = IsMissing(arg)  
        End Select  
    End Function  
    

    【讨论】:

    • 如果我能用这个方法我不,我使用的是Windows7/Access2010,应用程序将在WindowsXP/Access2003上运行,Excel文件应该是Excel97-2003。我的问题是,对于 excel 单元格上真正存在的值,我得到 null
    • 这适用于任何版本的 Access 和 Excel。它不使用或不依赖特定的库。试试看吧。
    • 使用我的代码,我可以读取 excel 文件中的数据。查询中没有问题。如果该列包含 A B C 4 我的代码读取 A,B,C 但 rsExcel.Fields(1).Value 在有 4 时返回 null。
    • 使用第二个解决方案我得到“在线自动化错误” Set xlo = GetObject("Excel.Application")"
    • 如果这对您有用,请标记答案,以便其他人更容易找到此帮助。
    【解决方案2】:

    我认为您首先需要将 Excel 数据中的任何数字转换为文本格式(格式化为文本的数字默认在角落有一个绿色三角形,可以使用错误检查选项来抑制)。我知道有两种方法可以做到这一点,一种用于单列,另一种用于更大范围:

    方法1)选择单个列,然后选择Data Tab > Text to Columns 点击next两次,在第三步选择Text选项然后点击Finish。

    方法 2) 复制整个表格或工作表,然后选择单元格格式并单击数字格式的文本。现在,您可以通过单击办公室剪贴板上的图标或将表格粘贴到记事本并复制并粘贴回 Excel 来粘贴为文本。 (Office剪贴板可以通过点击主页选项卡剪贴板部分右下角的箭头来激活)

    【讨论】:

    • 我的excel文件实际上不包含任何文本格式。应该可以将单元格的值读取为文本
    • 根据您的描述,您似乎有一个 Excel 表格,格式为通用数字格式,混合了数据类型(文本、数字、日期)。 Access 要求每列是单一数据类型,如果一列主要是文本但也包含一些数字,则数字将返回为 null - 它不会为您转换它们。当我遇到这个问题时,我发现最简单的方法是将 Excel 中的列转换为上面的文本格式,并且数据已导入 OK。您可以通过将表复制并粘贴到 Access 数据库窗口中来进行测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 2019-08-29
    相关资源
    最近更新 更多