【问题标题】:Append Fields in an Existing ADO Recordset在现有 ADO 记录集中追加字段
【发布时间】:2014-07-12 00:58:42
【问题描述】:

我在 Excel 中使用 ADO 记录集来获取一个巨大的 CSV(约 100 万行)并将其用作外部数据来创建 PivotCache 和 Pivottable。

我想编辑记录集以附加其他字段(列)并添加从字段之一计算的数据,即具有如下字符串数据的一周字段:

例如如果 A、B、C 是记录集字段,

    A         B        C        D        E
w 2011 01                       01    2011
w 2011 02                       02    2011
w 2011 03                       03    2011
w 2011 04                       04    2011
w 2012 05                       05    2012

然后我想追加字段 D、E 并向它们添加数据,如上所示,从列 A 中剥离,就像我在 excel 中所做的那样,

D = 值(右(A2,2)) E = 值(中(A2,3,4))

但我想使用 SQL 函数。

然后我使用这个附加的记录集来创建一个数据透视缓存和一个将它用作外部数据源的数据透视表。在代码中查看我的评论。我无法将记录集克隆到新的记录集中,因为它给了我一些书签不可用的错误。

以下给了我错误:

Option Explicit 

Sub GetCSV() 
Application.EnableEvents = False 
Application.DisplayAlerts = False 
Application.ScreenUpdating = False 

Dim sFileName As String 
Dim sFilePath As String 
Dim rngPivotDest As Range 
Dim pcPivotCache As PivotCache 
Dim ptPivotTable As PivotTable 
Dim SQL As String 
Dim sConnStrP1 As String 
Dim sConnStrP2 As String 
Dim cConnection As Object 
Dim rsRecordset As Object, RS As Object, Fld As Object 
Dim Sht As Worksheet 
Dim Conn As Object 

With ThisWorkbook 

Set rsRecordset = CreateObject("ADODB.Recordset") 
Set RS = CreateObject("ADODB.Recordset") 
Set cConnection = CreateObject("ADODB.Connection") 


sFileName = Application.GetOpenFilename("Text Files, *.asc; *.txt; *.csv", 1, "Select a      Text File", , False) 
sFilePath = Left(sFileName, InStrRev(sFileName, "\")) 
sFileName = Replace(sFileName, sFilePath, "") 

sConnStrP1 = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" 
sConnStrP2 = ";Extensions=asc,csv,tab,txt;FIL=text;Persist Security Info=False" 

cConnection.Open sConnStrP1 & sFilePath & sConnStrP2 
SQL = "SELECT * FROM [" & sFileName & "]" 
Set rsRecordset = cConnection.Execute(SQL) 


'****** THIS ENTIRE PART IS NOT WORKING****** 
With RS 
.cursorlocation = 3 'aduseclient 
.cursortype = 2 'adOpenDynamic 3 'adopenstatic 
'    For Each Fld In rsRecordset.Fields 
'        .Fields.append Fld.Name, Fld.Type, Fld.definedsize, Fld.Attributes,     Fld.adFldIsNullable 
'    Next Fld 
.locktype = 4 'adLockBatchOptimistic'3 'adlockoptimistic 
.Fields.append "WeekNumber", 3 'adinteger 
.Fields.append "Year", 7 'addate 

.Open 
.Update 

'do something to grab the entire data into RS 
Set RS = rsRecordset.Clone 

'or something like 
Set RS = rsRecordset.getrows 

'append some function code to the last 2 fields to strip YEAR & WEEK from 1st field. 
...... 
...... 


End With 
********************************* 

'Delete any connections in workbook 
On Error Resume Next 
For Each Conn In .Connections 
    Conn.Delete 
Next Conn 
On Error GoTo 0 

'Delete the Pivot Sheet 
On Error Resume Next 
For Each Sht In .Sheets 
If LCase(Trim(Sht.Name)) = LCase("Pivot") Then Sht.Delete 
Next Sht 
On Error GoTo 0 

'Create a PivotCache 
Set pcPivotCache = .PivotCaches.Create(SourceType:=xlExternal) 
Set pcPivotCache.Recordset = rsRecordset 

'Create a Pivot Sheet 
.Sheets.Add after:=.Sheets("Main") 
ActiveSheet.Name = "Pivot" 

'Create a PivotTable 
Set ptPivotTable =  pcPivotCache.CreatePivotTable(TableDestination:=.Sheets("Pivot").Range("A3")) 

With ptPivotTable 
    .Name = "PivotTable" 
    .SaveData = False 
End With 


With ptPivotTable 
    With .PivotFields("Level") 
       .Orientation = xlPageField 
       .Position = 1 
    End With 
With .PivotFields("Cat") 
    .Orientation = xlPageField 
    .Position = 1 
End With 
With .PivotFields("Mfgr") 
    .Orientation = xlPageField 
    .Position = 1 
End With 
With .PivotFields("Brand") 
    .Orientation = xlPageField 
    .Position = 1 
End With 
With .PivotFields("Descr") 
    .Orientation = xlRowField 
    .Position = 1 
End With 
End With 

ptPivotTable.AddDataField ptPivotTable.PivotFields("Sales Value from CrossCountrySales"), "Sum of Sales Value from CrossCountrySales", xlSum 

With ptPivotTable.PivotFields("Week") 
    .Orientation = xlColumnField 
    .Position = 1 
End With 

With ptPivotTable.PivotFields("Sum of Sales Value from CrossCountrySales") 
    .Calculation = xlNoAdditionalCalculation 
End With 

cConnection.Close 
Set rsRecordset = Nothing 
Set cConnection = Nothing 
Set Conn = Nothing 

End With 

Application.ScreenUpdating = True 
Application.DisplayAlerts = True 
Application.EnableEvents = True 

End Sub

【问题讨论】:

  • 您是否尝试过在 SQL 查询中创建和填充这些额外的列,而不是在之后添加它们?
  • 嗨蒂姆,我不知道如何通过 sql 添加这些列及其提取的数据。

标签: excel vba append clone recordset


【解决方案1】:

您可以在原始 SQL 查询中创建这些新字段。

这是一个简化的示例:我正在查询一个 txt 文件“week.txt”(它只有一列带有标题“week”和几行测试数据)并将记录集放到工作表中。

Sub GetCSV()

    Dim SQL As String
    Dim sConnStrP1 As String
    Dim cConnection As Object
    Dim rsRecordset As Object, RS As Object
    Dim Conn As Object, i As Integer

    Set rsRecordset = CreateObject("ADODB.Recordset")
    Set RS = CreateObject("ADODB.Recordset")
    Set cConnection = CreateObject("ADODB.Connection")

    sConnStrP1 = "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
                 "Dbq=C:\_Stuff\test\" & _
                 ";Extensions=asc,csv,tab,txt;FIL=text;Persist Security Info=False"

    cConnection.Open sConnStrP1

    'create new columns based on "week" column
    '  1*(....) coerces to number
    SQL = "SELECT [week], 1*(right(week,2)) as wk_num, 1*(mid(week,3,4)) as year FROM [week.txt]"

    Set rsRecordset = cConnection.Execute(SQL)

    'drop to sheet...
    With ActiveSheet.Range("D5")
        For i = 0 To rsRecordset.Fields.Count - 1
            .Offset(0, i).Value = rsRecordset.Fields(i).Name
        Next i
        .Offset(1, 0).CopyFromRecordset rsRecordset
    End With


End Sub

【讨论】:

  • 我的 sql 查询正在从 CSV 中选择整个数据,稍后将用于创建数据透视表。我没有看到您选择 csv 数据,但您只定义了一个选择查询来查询周列并创建年和周数列。我没有将任何数据放到工作表中,而是创建一个外部数据透视缓存并使用它来创建数据透视表。我没有将列附加到源 csv 的原因,因为它有大约 100 万行,我不知道该怎么做。我想要记录集中的额外周数和年份列,以便它们出现并可以在数据透视表中使用。
  • 感谢蒂姆,编辑 SQL 查询有效。 SQL = "SELECT *, [week], 1*(right(week,2)) as WeekNumber, 1*(mid(week,3,4)) as Year FROM [" & sFileName & "]" '[week. txt]"
  • 很高兴你让它工作了 - 我的例子只是为了说明一般的方法:我知道你正在用你的数据集做一些不同的事情。
  • 是的,我已经发布了 3 年的产品销售数据,即跨越 156 周,我想以某种方式在 52 周内正确放置,因为我的想法是新产品一旦推出就不会运行超过 52 周。几周之间可能会有空白(空白,即没有销售),但销售周的总计数在 3 年内不会超过 52 周。逻辑是任何产品销售从第一周开始,即 w 2011 01 但总销售周数
  • 在这种情况下,整个销售周从周列开始转移:52-销售周计数+1。关于如何在 SQL 查询中将其实现为另一个名为“新周”的列的任何想法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
相关资源
最近更新 更多