2016-08-15 10 views
1

私はこのような2つのスプレッドシートを持っています: Spreadsheet2から始めれば、vlookupで値を取得できます。 しかし、私はスプレッドシート1から始める必要があります。私は行を追加する必要があります。これは小さなデータですが、実際には巨大なものです(20000行以上)。Excel vlookup複数の値を追加して重複行を追加する

Spreadsheet1:

Category Type NumItem 
Air   B747 10 
Ground  TBus1 15 
Air   B777 20 
Air   A380 5 

Spreadsheet2:

Type TypeElement NumEngine 
B747 747T1   2 
B747 747T2   4 
B747 747T3   8 
Tbus1 TbusT1   0 
B777 777T1   6 
B777 777T2   4 
A380 380T1   10 

私はスプレッドシートにこれらをマージしたいです。両方の一致のTypeを見ることができますが、それぞれの型には複数の "TypeElement"があります。

は、私は、これはExcelでの関数を使用して行うことができ、それは

Category Type NumItem TypeElement NumEngine 
Air   B747 10   747T1   2 
Air   B747 10   747T2   4 
Air   B747 10   747T3   8 
Ground  TBus1 15   TbusT1   0 
Air   B777 20   777T1   6 
Air   B777 20   777T2   4 
Air   A380 5   380T1   10 

のようなものを見てみたいか..私はVBA /マクロを使用する必要がありますか? Rを使ってどのようにこれを行うことができるか知っている人は、私が使用すべき式/パッケージをコメントしてください。

ありがとうございました!

+2

に参加するためにSQLコマンドを使用してExcelからのインポート/エクスポートすることができ、いくつかのライブラリがあります。両方のスプレッドシートを2つのデータフレームに読み込んでから、「merge」を使用してください。 –

+0

Spreadsheet1で始める必要がある理由は、Spreadsheet1のどの項目にSpreadsheet2の対応するデータがないかを調べる必要があるためです。たとえば、Spreadsheet1にB700がある場合、Spreadsheet2には空白/エラーセルが見つかります。 –

+0

スプレッドシートを使用する必要はありません(また、20k行の場合は、そうしたくありません)。'readxl'または好みのパッケージを使ってRにインポートし、' merge'(ここでは 'all = TRUE')を使うか、混乱するような場合は、dplyrパッケージの' * _join'関数(ここでは 'full_join') SQLスタイル。また、 'TBus1'と' Tbus1'の間に矛盾があることに注意してください。だから、 'toupper'や' tolower'をすべて取りたいと思うかもしれません。 – alistaire

答えて

2

@ r-schifiniと同様に、Excelファイルをインポートするために使用できるライブラリがいくつかあります。ここではreadxlパッケージを使用します。最初のスプレッドシート(​​スプレッドシート1)のすべての行を保持するには、mergeファンクションのall.x=TRUEを指定します。詳細は?mergeを参照してください。 Spreadsheet1にもう1つの行を追加しました。タイプはB700の偽のデータです。

library(readxl) 
ss1 <- read_excel(path = "spreadsheet1.xlsx", sheet = 1) 
ss2 <- read_excel(path = "spreadsheet2.xlsx", sheet = 1) 


out <- merge(ss1, ss2, all.x=TRUE) 
out 
# Type Category NumItem TypeElement NumEngine 
# 1 A380  Air  5  380T1  10 
# 2 B700  Air  8  <NA>  NA 
# 3 B747  Air  10  747T1   2 
# 4 B747  Air  10  747T2   4 
# 5 B747  Air  10  747T3   8 
# 6 B777  Air  20  777T1   6 
# 7 B777  Air  20  777T2   4 
# 8 TBus1 Ground  15  <NA>  NA 

なぜ8列目にNAがありますか?これは、あなたのタイプがスプレッドシート1にTBus1、スプレッドシート2にTbus1があるからです。このような問題を回避するために、マージを行う前に大文字小文字を上に変更することができます。

ss1$Type <- toupper(ss1$Type) 
ss2$Type <- toupper(ss2$Type) 
out <- merge(ss1, ss2, all.x=TRUE) 
out 
# Type Category NumItem TypeElement NumEngine 
# 1 A380  Air  5  380T1  10 
# 2 B700  Air  8  <NA>  NA 
# 3 B747  Air  10  747T1   2 
# 4 B747  Air  10  747T2   4 
# 5 B747  Air  10  747T3   8 
# 6 B777  Air  20  777T1   6 
# 7 B777  Air  20  777T2   4 
# 8 TBUS1 Ground  15  TbusT1   0 
0

いくつかのアイデア 1)行を結合し、ソート機能を使用して、要素アイテムの昇順または降順の値をソートすることができます。たとえば、カスタムソートやフィルタを実行します。

2)値をどのように分類するかを選択する必要があります。カテゴリ別?タイプ別?アイテムをネイティブにグループ化する方法はいくつかあります。変数間のリンクを設定する。

0

私はアクセスファイル(c:\ testdb.mdb)にtb1とtb2を移動するVBAを使用します。 openxlsx、XLConnect: はその後、彼らに


Sub Main() 
    Dim adoxCat As Object, adoConn As Object, adoRst As Object, var As Variant, strSQL As String 
    Dim i As Long 

'make an empty mdb file' 
    If Dir("C:\testdb.mdb") = "" Then 
     Set adoxCat = CreateObject("ADOX.catalog") 
     adoxCat.Create "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\testdb.mdb;" 
     Set adoxCat = Nothing 
    Else 
     MsgBox "C:\testdb.mdb is existed.", vbCritical 
     Exit Sub 
    End If 
'create an ADO connection' 
    On Error Resume Next 
    Set adoConn = CreateObject("adodb.connection") 
    With adoConn 
     .Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\testdb.mdb;" 
     If .State 1 Then 
      MsgBox "Cannot create ADO Connection.", vbCritical 
      Set adoConn = Nothing 
      Exit Sub 
     End If 
    End With 
'create two Tables in the mdb file.' 
    With adoConn 
     .Execute "CREATE TABLE tb_1 (Category varchar, Type varchar, NumItem number)" 
     .Execute "CREATE TABLE tb_2 (Type varchar, TypeElement varchar, NumEngine number)" 

'move data in excel to mdb file' 
     var = toArray(Worksheets(1)) 
     For i = LBound(var, 1) To UBound(var, 1) 
      strSQL = "INSERT INTO tb_1 (category, type, NumItem) VALUES(" 
      strSQL = strSQL & " '" & var(i, 0) & "'," 
      strSQL = strSQL & " '" & var(i, 1) & "'," 
      strSQL = strSQL & " " & var(i, 2) & ");" 
      .Execute strSQL 
     Next i 

     var = toArray(Worksheets(2)) 
     For i = LBound(var, 1) To UBound(var, 1) 
      strSQL = "INSERT INTO tb_2 (Type, TypeElement, NumEngine) VALUES(" 
      strSQL = strSQL & " '" & var(i, 0) & "'," 
      strSQL = strSQL & " '" & var(i, 1) & "'," 
      strSQL = strSQL & " " & var(i, 2) & ");" 
      .Execute strSQL 
     Next i 

'Use SQL Join statement to Join two tables' 
     strSQL = "SELECT * FROM tb_1 left join tb_2 on tb_1.type = tb_2.type;" 
     Set adoRst = .Execute(strSQL) 
'output the result to excel worksheet(3)' 
     Worksheets(3).Range("A1").CopyFromRecordset adoRst 

     .Close 
    End With 
    Set adoConn = Nothing 
'remove the mdb file' 
    Kill "c:\testdb.mdb" 
End Sub 


Function toArray(from_WSht As Worksheet) As Variant 
    Dim strPath As String, myRng As Range, rw As Range, c As Range 
    Dim i As Long, j As Long, dt As Variant 

    Set myRng = from_WSht.Range("a1").CurrentRegion 
    If not myRng.Rows.Count > 1 Then GoTo errHdr 
     ReDim dt(myRng.Rows.Count - 1, myRng.Columns.Count - 1) As Variant 
     i = 0 
     For Each rw In myRng.Rows 
      If rw.Row > 1 Then 
       j = 0 
       For Each c In rw.Cells 
        dt(i, j) = c.Value 
        j = j + 1 
       Next c 
       i = i + 1 
      End If 
     Next rw 

    toArray = dt 
    Exit Function 
errHdr: 
    toArray = 0 
End Function 

enter image description here

関連する問題