1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

xlwings rangeの配列アクセス

Posted at

ドキュメントの不足

フリーウェア系ソフトによくあることだが、xlwingsも公式ドキュメントに書かれていることが不足している。
xlwingsに不足している機能を補うモジュールを作ろうとして、現状のxlwingsでどこまで出来るのかを確認することを意識しながら、ソースを読んでいて分かった。
公式ドキュメントのAPIのところに書いてあることは、ほとんどソースファイル中のdocstringとして書かれている。ただし、各クラスのメソッドのうち、__getitem__などのアンダーバー2つで始まる特殊メソッドについては、公式ドキュメントに書かれていない。

rangeオブジェクトに配列アクセス

1次元配列としてのアクセス

下記の様に、添え字1つでアクセスすると、範囲内のセルを1次元的に並べた個々のセルに対してのrangeオブジェクトへのアクセスとなる。

import xlwings as xw
wb = xw.Book
rng = wb.sheets[0].range("A1:B2")
for i in range(len(rng)):
    print(rng[i].address)
# --> 
$A$1
$B$1
$A$2
$B$2

2次元配列としてのアクセス

上記の例に違和感を持った人もいると思う。rngは2次元の領域を持つゆえ、通常のpythonの2次元配列(リストのリスト)と同様であれば、rng[0].address$A$1:$B$1を返すのであるから。

リストのリストとしてrngにアクセスすると、以下のようにエラーとなる。

print(rng[0][1])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_19144\1066751280.py in <cell line: 1>()
----> 1 print(rng[0][1])

~\AppData\Roaming\Python\Python39\site-packages\xlwings\main.py in __getitem__(self, key)
   2407             k = key + n if key < 0 else key
   2408             if k < 0 or k >= n:
-> 2409                 raise IndexError("Index %s out of range (%s elements)." % (key, n))
   2410             else:
   2411                 return self(k + 1)

IndexError: Index 1 out of range (1 elements).

これは、rng[0]が単一のセル$A$1のみに対するrangeオブジェクトとなっているために生じているエラーである。

では、2次元的に扱いたい場合は、どうしたら良いか。xlwingsのソース中のclass range__getitem__メソッドを見ると、2つの要素を持つtupleに対応したコードが先頭にある。
2次元的にアクセスする正しい方法を以下の例のように、[ ]内に行と列を並べて書く方法である。

nr,nc = rng.shape
for i in range(nr):
    for j in range(nc):
        print(rng[i,j].address)
# --> 
$A$1
$B$1
$A$2
$B$2

__getitem__メソッドの先頭にあるコードであることから、この方法がrangeオブジェクトに対する配列アクセスの本筋の方法だと思われる。

以下の例の様にrange内の一部の要素の書式を変更したい場合に、この様な配列アクセスを用いると良い。

rng[1,0].api.Font.Bold = True # セルA2を太字にする

なお、numpyと同様のスライスによるアクセスにも対応しているので、範囲内の特定の列のみなどのrangeオブジェクトを得たい場合に用いると良い。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?