【Python × Excel】ブックやシートをまたいで複数列のコピペをする方法

#はじめに
Excelでブックやシートをまたいで、複数列のデータをコピペしたいときありませんか？
この記事では、Pythonを使ってExcel上でこれを実行する方法を解説します。

今回は架空の会社の社員データ.xlsxと評価データ.xlsxという2つのブックを例に、コードの書き方を説明していきます。

社員データ
![社員データ-基本情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646654/b4773d34-23fa-05e0-b2da-705f8d751c14.png)
評価データ
![評価データ-評価.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646654/bc1eea75-f5ea-a0c6-1ca5-cb60df454a74.png)

##準備
まず初めに必要なライブラリをインポートしておきましょう。

```python
import os
import openpyxl as px
```

osはカレントディレクトリの確認や変更といった、OSの機能をPythonで使うためのライブラリです。後述するように、今回は利用したいExcelファイルのあるディレクトリに異動するために使います。
openpyexcelは、PyhtonでExcelを利用するときに使うライブラリです。今回に限らずPythonでExcelを操作するときは、必ずインポートしておきましょう。

##ワークブックとワークシートの読み込み
必要なライブラリをインポートしたら下記のように、使うワークブックとワークシートを読み込みます。

```python
#該当ファイルのあるディレクトリに異動
os.chdir('C:\\Users\\ユーザー名\\Documents\\Qiita用サンプル')


#社員データのワークブックとワークシートを読み込み
wb1 = px.load_workbook('社員データ.xlsx')
ws1 = wb1['基本情報']
ws2 = wb1['経歴']

#評価データのワークブックとワークシートの読み込み
wb2 = px.load_workbook('評価データ.xlsx')
ws3 = wb2['評価']
```


まずはos.chdir()でカレントディレクトリを移動します。Users以降は人によってパスが違うと思いますが、とにかく扱いたいExcelファイルのあるフォルダのパスを入れてください。

ワークブックの読み込みは、px.load_workbook(ファイル名)で行います。カレントディレクトリを正しく移動できていれば、絶対パスではなくファイル名だけで読み込むことができます。

そのあとws1 = wb1[シート名]という感じでワークシートを読み込みます。社員データ.xlsxにはシートが2つ存在するため、今回はws1、ws2という風に２回読み込んでいます。

ワークブックが複数ある場合は、上記コードのように変数名を変えて同じようにpx.load_workbook()で読み込んでいきます。

##シートをまたいで指定した列をコピペ
それではいよいよ、シートをまたいだコピペをしていきます。
今回は社員データブックの経歴シートの"高校", "大学"カラムをコピーして。基本情報シートのE列とF列にペーストしたいと思います。

C、D列を最後までコピーして
![経歴シート1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646654/ce04f603-94e1-d0c3-c156-6e7f72d8072b.png)
基本情報シートのE、F列に貼り付けたい
![基本情報シート１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646654/1ab76bd3-c5b3-a711-fa56-47ece50c05f1.png)

まずコードは下記のようになります。

```python
def copy_paste1():
    for i in range(1, ws2.max_row + 1):
        highschool = ws2.cell(row = i, column = 3).value
        ws1.cell(row = i, column = 5, value = highschool)
        bachelor = ws2.cell(row = i, column = 4).value
        ws1.cell(row = i, column = 6, value = bachelor)
        i += 1
    wb1.save(filename = '社員データ.xlsx')

copy_paste1()
```


コピペを行うセルが1つの時はfor文はいりませんが、今回のように複数のセルを扱う場合はfor文のループ処理を利用すると簡単です。
rangeのスタートはコピーしたい行を指定しましょう。今回はヘッダーを含めてコピーしたいので１を指定しています。もしヘッダーを除いてコピーしたい場合は、２を指定しましょう。
そしてrangeの終了値ですが、max_row + 1と書くことでデータが入ってるカラムの最後までループを行うことができます。max_rowはデータが入っているセルをカウントして、最終行が何行目かを教えてくれるメソッドです。
ちなみに+1するのは、range()の性質で終了値をカウントしてくれないためです（例えばRange(0,10)とした場合はカウントされるのは0~9までですよね？）。

ちなみに最後にi += 1と書いてますが、Pythonの性質上この記載がなくても勝手にiが1ずつ加算されるので本例は不要です。本コードでは見た目をわかりやすくするために、あえて記載しております。

正しくコードが書けていれば、このようになるでしょう。

![成果物.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646654/9f8830db-ee49-657b-3006-722a18fb11a8.png)

```python
import os
import openpyxl as px

#該当ファイルのあるディレクトリに異動
os.chdir('C:\\Users\\ユーザー名\\Documents\\Qiita用サンプル')

#社員データのワークブックとワークシートを読み込み
wb1 = px.load_workbook('社員データ.xlsx')
ws1 = wb1['基本情報']
ws2 = wb1['経歴']

#評価データのワークブックとワークシートの読み込み
wb2 = px.load_workbook('評価データ.xlsx')
ws3 = wb2['評価']

def copy_paste1():
    for i in range(1, ws2.max_row + 1):
        highschool = ws2.cell(row = i, column = 3).value
        ws1.cell(row = i, column = 5, value = highschool)
        bachelor = ws2.cell(row = i, column = 4).value
        ws1.cell(row = i, column = 6, value = bachelor)
        i += 1
    wb1.save(filename = '社員データ.xlsx')

copy_paste1()

```