Vlookupは数千行に及んで使用しても良いのか?

libreofficeのvlookupを使い、食べたものの記録をしようと思います。以前にも同種の質問をしました。

sheet1で食べたものの食品名を入れることで、sheet2に登録した食品成分が入力されるという仕組みです。この際、vlookup関数を大量に使います。画像で言うとC2:E20の範囲になります。
毎日つけていくとすぐに数千行は越えるでしょう。

別の質問

このような仕組みだと後々問題になったりしますか?
改善点があれば教えて下さい。毎日つけるものですから、「こうすれば楽になる」という観点からのアドバイスがいただければと思います。

サンプルファイル

vlookup_test.ods (15.8 KB)

何も調査してないけど、一応メモ。

https://bugs.documentfoundation.org/show_bug.cgi?id=139444

えー…、またまた野暮かもしれませんが…(汗)。

懸念されている「問題」というのは、「処理が重く実用に耐えなくなる」ということ、でしょうかね…「vlookup関数を大量に使います」「毎日つけていくとすぐに数千行は越える」という言葉が見られるということは。

私の考えでは、やってみないと分からないのではないかと思えます。使用する数式の数や複雑さ、参照データのレコード数や項目数、マシンパワーなど、条件によって違ってくると思います。
参考までに、質問に添付いただいたサンプルファイルの例について少し試してみました。

  • 試験条件
    • 全てのVLOOKUP()式において第1引数が$B$2:$B$20とあるものを、例えば2行目では$B2(3行目なら$B3)に変更(でないと次項でコピーしても機能しません)。
    • A2:E2をA21:E50000にコピー。
  • 結果
    • 手元環境ではストレスなく軽快に動作。
    • ただしファイルの読込・保存には相応の時間を要する。
    • コピー時にも多少の時間は要する(50000行で10秒弱?)。

まぁ…、さしたる問題にはなりませんでした。


himajin100000さんが挙げられたバグ報告の状況は手元で再現しました。
VLOOKUP()を大量にコピペした場合に処理が帰ってこなくなるという話で、実際そのようになり、小分けのコピーでも実用に耐えない重さになりました。

ただこの例では、

  • 本質問のsheet1に対応するシートにおいて、行数こそ90行と限定的なものの、使用列数が上限たる1024列もあってその全て(A列除く)にVLOOKUP()が設定されている(本質問サンプルファイルでは3列ですね)
  • sheet2に対応するシートの行数(つまりVLOOKUP()で検索するデータのレコード数)が約68000行もある(本質問サンプルファイルでは3行ですね)

など、規模の大きさが極端で、ご質問と同列に比較していい話とは思えません。
というか…このような規模の処理を表計算ソフトにさせようとすること自体が狂気の沙汰と、私などには思えます(補足後述)。
「ExcelやGnumericではサクッと動く」と報告されているのが苦しいところですが…本当にそんなに軽快なのかどうか、自分はいずれも使える環境になくて定かでありません。


bgegg2dさんのやりたいことは、私の目からは、本来表計算ソフトではなく、データベースやプログラミング(スクリプトやマクロ含む)の領域であるように見えています。
規模が小さければ表計算ソフトを使った真似事で済ませることは出来て、私も含め実際そのような使い方をしている人は多いと思います。が、規模を大きくするつもりなのなら、データベース利用の検討をオススメします。
「データ検索」というのはコンピューターにとって結構大変な処理です。そのためにデータベースというアプリケーションカテゴリーが独立して成立していて、LibreOfficeにもBaseというデータベースアプリケーションが備わっています(私はスクリプトで処理する派なのでBaseは全然使っていませんが…)。
まぁ…表計算ソフトに比べると(情報量も含め)少々ハードル高いですが…(苦笑)。

ちなみに以前のスレッドで話題になったGoogleスプレッドシートのquery()関数というのも、表計算ソフトにより本格的なデータベースの真似事をさせようとする試みなのかも知れません。


データベースやプログラミングを使うのでなければ、これはbgegg2dさんのニーズを無視する話になってしまいますが、そもそもVLOOKUP()による自動引用などやめてしまって、データを手作業でコピペする方が「楽」なのではないかと思えたりもします。
sheet2の参照データが3件しかないのなら簡単です。またわざわざsheet2を参照するまでもなく、sheet1の過去のデータをコピペしても良さそうです。
この辺りはsheet2の参照データ数がどれくらいになることを想定されているのかにも依ってくるのでしょうが…。数があまり増えてくるようだと、処理の重さとの兼ね合いがまた懸案になってはきます。
表計算ソフトというのはそういう使い方をするツールと私は理解しています。


最後に、細々とした提案を。

  • (再掲)VLOOKUP()の第1引数(検索基準)はセル範囲ではなく単一セルを指定するものと思います。
  • VLOOKUP()の第2引数(行列)はSheet2.$A:$Dなどとしておくと行追加が楽になります(処理速度とも相談かも知れませんが…)。
  • B列の入力規則も同様です。
  • VLOOKUP()の第4引数(SortedRangeLookup)はFALSE()でなく0で良いのでは。大差ないかも知れませんが、関数呼び出しは余計な処理を増やす可能性が否めない気がします。
  • 同様に処理を減らす(軽くする)観点からは、VLOOKUP()より先日の例のようにMATCH()とINDEX()の組み合わせをオススメします。検索処理が1行につき1度で済みます。(バグ報告の例ではこの方法が使えない使い方をしています。)

そうですね。コピペのほうが楽かもしれません(´・ω・`)、、、
下手に関数などを使おうとして、手段が目的化しているような気がします。

結局、欲しいのは1日の栄養量であり、1日の栄養量を元に食事を改善していくのが目的です。
365日の合計値なんてのは必要ありませんので、栄養価を変数化して、一括で変更するなんて言う必要性は薄いわけですね。

とりあえず運用して問題が出たらその時に考えることにします。

1 Like