【问题标题】:excel vba sql server data import "type mismatch error"excel vba sql server 数据导入“类型不匹配错误”
【发布时间】:2012-04-12 02:19:26
【问题描述】:

我正在尝试创建一个宏,它将一些数据从 SQL Server 2005 拉入 Excel 2003。

SQL 代码在此宏中,其中部分代码来自 Excel 单元格中的值。这在一定程度上可行,但是当我用于 SQL 代码的 Excel 单元格中的数据超过公式预览中的一行(或大约 170 个字符)时,我会收到“类型不匹配”错误。否则它可以正常工作。

With ActiveSheet.QueryTables.Add(Connection:=Array( _
"OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data       Source=anglobisql;Use Procedure for Prepare=1;Auto " _
    , _
    "Translate=True;Packet Size=4096;Workstation ID=MyIDHere;Use Encryption for Data=False;Tag with column collation when possible=F" _
    , "alse;Initial Catalog=DATABASENAME"), Destination:=Range("A1"))
    .CommandType = xlCmdSql
    .CommandText = Array("SELECT COLUMN1, COLUMN2 FROM TABLENAME (nolock) WHERE COLUMN1 IN (" & ActiveWorkbook.Sheets("Sheet1").Range("e607").Value & ")")
    .Name = "DATABASE TABLENAME"
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .BackgroundQuery = True
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .PreserveColumnInfo = True
    .SourceConnectionFile = _
    "H:\My Data Sources\DATABASE TABLENAME.odc"
    .Refresh BackgroundQuery:=False

显然所有的databasename 和tablename 都正确填写了。

知道为什么会下降(是否有字符限制,或者是否因为单元格值继续到 Excel 公式预览栏中的下一行而失败?如何解决这个问题?

非常感谢,

亚历克斯

【问题讨论】:

  • 32,767 个字符是 Excel 单元格的限制。我的猜测是您的所有数据都插入到单个单元格 (A1) 中。
  • 不太确定您指的是输入还是输出。对于输出:当 sql 查询正常工作时,数据来自不同的单元格,所以这不是问题对于输入:截止似乎是大约 170 个字符,所以 32,767 又不是问题。
  • 我可以看到 Excel 中“编辑 OLE DB 查询”的“命令文本”中确实存在文本限制,但我再次认为我在其中。
  • 单元格 E607 中的数据是什么? (格式,特殊字符,...?)。它应该看起来像“SELECT ColumnA FROM TableA ..”
  • 只是自定义的 SQL 代码,在本例中是数字列表,因此请从 tableA 中选择 colA, colB where colA IN (602023, 45023, 230203, 230203)。同样,在单元格达到一定大小之前,代码没有真正的问题

标签: sql excel vba import


【解决方案1】:

Excel 单元格超过 170 个字符应该不会导致任何问题。我建议将出错的行分开,以帮助准确找出问题所在。

替换这个:

    .CommandText = Array("SELECT COLUMN1, COLUMN2 FROM TABLENAME (nolock) WHERE COLUMN1 IN (" & ActiveWorkbook.Sheets("Sheet1").Range("e607").Value & ")")

有了这个:

    Dim rng As Range, sSql As String
    Set rng = ActiveWorkbook.Sheets("Sheet1").Range("e607")
    Debug.Print "Range.Value = |" & rng.Value & "|"
    sSql = "SELECT COLUMN1, COLUMN2 FROM TABLENAME (nolock) WHERE COLUMN1 IN (" & rng.Value & ")"
    Debug.Print "SQL = |" & sSql & "|"
    .CommandText = sSql

Debug.Print 打印到即时窗口,因此您可以仔细检查变量是否符合您的预期。我喜欢在调试字符串时使用| 而不是",因为我在字符串中几乎没有|

另外,我不会为CommandTextConnection 使用Array()。为了便于阅读,我会重做你的第一行,使其看起来像这样。

With ActiveSheet.QueryTables.Add( _
        Connection:="OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI" _
                & ";Persist Security Info=True;Data Source=anglobisql" _
                & ";Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096" _
                & ";Workstation ID=MyIDHere;Use Encryption for Data=False" _
                & ";Tag with column collation when possible=False;Initial Catalog=DATABASENAME" _
      , Destination:=Range("A1"))

【讨论】:

    【解决方案2】:

    这是通过删除数组文本来解决的

    .CommandText = Array("SELECT COLUMN1, COLUMN2 FROM TABLENAME (nolock) WHERE ...
    

    变成

    .CommandText = ("SELECT COLUMN1, COLUMN2 FROM TABLENAME (nolock) WHERE ...
    

    【讨论】:

      猜你喜欢
      • 2017-04-12
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 2014-01-05
      • 2015-10-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多