2017-06-19 281 views
1

我使用ADO中的此代码在工作簿之间复制粘贴数据。来自第一个工作簿的数据是垂直的。我想复制它并以横向粘贴到其他工作簿。我如何用下面的代码来做到这一点?在此先感谢VBA将数据从一个工作簿复制,粘贴并转置到其他工作簿

Public Sub GetData(SourceFile As Variant, SourceSheet As String, _ 
        SourceRange As String, TargetRange As Range, Header As Boolean, UseHeaderRow As Boolean) 
' 30-Dec-2007, working in Excel 2000-2007 
    Dim rsCon As Object 
    Dim rsData As Object 
    Dim szConnect As String 
    Dim szSQL As String 
    Dim lCount As Long 
' Create the connection string. 
If Header = False Then 
    If Val(Application.Version) < 12 Then 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 8.0;HDR=No;"";" 
    Else 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 12.0;HDR=No;"";" 
    End If 
Else 
    If Val(Application.Version) < 12 Then 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 8.0;HDR=Yes;"";" 
    Else 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 12.0;HDR=Yes;"";" 
    End If 
End If 

If SourceSheet = "" Then 
    ' workbook level name 
    szSQL = "SELECT * FROM " & SourceRange$ & ";" 
Else 
    ' worksheet level name or range 
    szSQL = "SELECT * FROM [" & SourceSheet$ & "$" & SourceRange$ & "];" 
End If 

On Error GoTo SomethingWrong 

Set rsCon = CreateObject("ADODB.Connection") 
Set rsData = CreateObject("ADODB.Recordset") 

rsCon.Open szConnect 
rsData.Open szSQL, rsCon, 0, 1, 1 

' Check to make sure we received data and copy the data 
If Not rsData.EOF Then 

    If Header = False Then 
     TargetRange.Cells(1, 1).CopyFromRecordset rsData 

    Else 
     'Add the header cell in each column if the last argument is True 
     If UseHeaderRow Then 
      For lCount = 0 To rsData.Fields.Count - 1 
       TargetRange.Cells(1, 1 + lCount).Value = _ 
       rsData.Fields(lCount).Name 
      Next lCount 
      TargetRange.Cells(2, 1).CopyFromRecordset rsData 
     Else 
      TargetRange.Cells(1, 1).CopyFromRecordset rsData 
     End If 
    End If 

Else 
    MsgBox "No records returned from : " & SourceFile, vbCritical 
End If 

' Clean up our Recordset object. 
rsData.Close 
Set rsData = Nothing 
rsCon.Close 
Set rsCon = Nothing 
Exit Sub 
+1

检查:[复制使用VBA Excel工作表之间的数据(https://www.codeproject.com/Tips/1187802/Copy-Data-Between-Excel-Sheets-using-VBA)如果你想要转换数据,您有2个选项:1)使用[MS Access SQL转换语句](https://msdn.microsoft.com/en-us/library/bb208956(v = office.12).aspx)或使用2 )Excel [转置方法](https://msdn.microsoft.com/VBA/Excel-VBA/articles/worksheetfunction-transpose-method-excel) –

回答

1

使用getrows! getrows方法从记录集转置类型获取数据。

昏暗VDB

VDB = rsData.getRows

TargetRange.Cells(1,1).resize(UBOUND(VDB,1)+ 1,UBOUND(VDB,2)+1)= VDB

getRows函数获取记录集的数据作为数组,但转置。 因此,该阵列这样

VDB(0,0),VDB(0,1),....,VDB(0,N)

VDB(1,0),VDB(1 ,1),....,VDB(1,N)

....

VDB(C,0),VDB(C,1),...,VDB(C,N )

在这个例子中,n + 1是recordcount,c + 1是Fieldscount。 它也是eboundals Ubound(vdb,2)+1,Ubound(vDB,1)+1。

这是所有代码。

Public Sub GetData(SourceFile As Variant, SourceSheet As String, _ 
        SourceRange As String, TargetRange As Range, Header As Boolean, UseHeaderRow As Boolean) 
' 30-Dec-2007, working in Excel 2000-2007 
    Dim rsCon As Object 
    Dim rsData As Object 
    Dim szConnect As String 
    Dim szSQL As String 
    Dim lCount As Long 
' Create the connection string. 
If Header = False Then 
    If Val(Application.Version) < 12 Then 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 8.0;HDR=No;"";" 
    Else 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 12.0;HDR=No;"";" 
    End If 
Else 
    If Val(Application.Version) < 12 Then 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 8.0;HDR=Yes;"";" 
    Else 
     szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
        "Data Source=" & SourceFile & ";" & _ 
        "Extended Properties=""Excel 12.0;HDR=Yes;"";" 
    End If 
End If 

If SourceSheet = "" Then 
    ' workbook level name 
    szSQL = "SELECT * FROM " & SourceRange$ & ";" 
Else 
    ' worksheet level name or range 
    szSQL = "SELECT * FROM [" & SourceSheet$ & "$" & SourceRange$ & "];" 
End If 

On Error GoTo SomethingWrong 

Set rsCon = CreateObject("ADODB.Connection") 
Set rsData = CreateObject("ADODB.Recordset") 

rsCon.Open szConnect 
rsData.Open szSQL, rsCon, 0, 1, 1 

' Check to make sure we received data and copy the data 
If Not rsData.EOF Then 
    Dim vDB 
    vDB = rsData.getRows 
    If Header = False Then 
     'TargetRange.Cells(1, 1).CopyFromRecordset rsData 
     TargetRange.Cells(1, 1).Resize(UBound(vDB, 1) + 1, UBound(vDB, 2) + 1) = vDB 
    Else 
     'Add the header cell in each column if the last argument is True 
     If UseHeaderRow Then 
      For lCount = 0 To rsData.Fields.Count - 1 
       TargetRange.Cells(1 + lCount, 1).Value = _ 
       rsData.Fields(lCount).Name 
      Next lCount 
      'TargetRange.Cells(2, 1).CopyFromRecordset rsData 
      TargetRange.Cells(1, 2).Resize(UBound(vDB, 1) + 1, UBound(vDB, 2) + 1) = vDB 
     Else 
      TargetRange.Cells(1, 1).Resize(UBound(vDB, 1) + 1, UBound(vDB, 2) + 1) = vDB 
     End If 
    End If 

Else 
    MsgBox "No records returned from : " & SourceFile, vbCritical 
End If 

' Clean up our Recordset object. 
rsData.Close 
Set rsData = Nothing 
rsCon.Close 
Set rsCon = Nothing 
Exit Sub 
SomethingWrong: 
    MsgBox "The file name, Sheet name or Range is invalid of : " & SourceFile, _ 
      vbExclamation, "Error" 
    On Error GoTo 0 
End Sub 
+0

谢谢。它工作完美 –

1

使用此通用程序来移调范围:

TransposeRange(TargetRange.Resize(rsData.RecordCount, rsData.Fields.Count)) 

的:

Sub TransposeRange(r As Range) 
    Dim ar: ar = Application.Transpose(r.Value2) 
    r.ClearContents 
    r.Resize(r.Columns.Count, r.Rows.Count).value = ar 
End Sub 

从代码中调用它,您可在线路rsData.Close之前添加此Recordset对象的方法RecordCount经常令人烦恼。我们可以通过不同的方式猜测复制记录的数量来克服它。两种方法是可能的:

1-记忆的由CopyFromRecordset

2-返回作为“懒修复” fecthed记录的数目,得到复制的行从该范围的数:

TransposeRange(TargetRange.Resize(TargetRange.End(xlDown).Row + 1 -TargetRange.Row, _ 
    rsData.Fields.Count)) 

最后,请注意,excel的行数多于列数的空间。如果您的数据记录的数量超过了列数,那么操作是不可能的。

+0

它不起作用。错误说“范围无效”。 –

+0

@AdryanPermana'RecordCount'往往令人烦恼。尝试添加到我的答案的任何其他方法。 –

相关问题