OpenOfficeで会員向け料金と一般向け料金を区別して値段を表示する

数式が長いので、うまく表示できていないところがあります。すみません。
改善できるように調整中です。画像とサンプルファイルで詳細をご覧ください。

下の表では、A列からF列の範囲に顧客のある日の注文状況が表示されています。

送信者 OpenOffice
このサンプルファイルは、SKYDRIVEからcalc112.odsをダウンロードしてください。
単価は会員と一般で、異なります。
そこで、H:I列を参照するか、K:L列を参照するかはB列に表示されている顧客のステータスを元にして、適用する料金表をその都度変える必要があります。
参照する料金表をその都度変更できる数式を紹介します。

単価を表示するための数式は、VLOOKUP関数を用いて作成しています。
=VLOOKUP(C2;INDIRECT(ADDRESS(1;MATCH(B2;$A$1:$L$1;0));0):INDIRECT(ADDRESS(4;MATCH(B2;$A$1:$L$1;0)+1));2)


この数式の主なポイントは、

  1. MATCH関数を使用して、一般・会員の種別を判断。
  2. その情報をもとにADDRESS関数でアドレスの文字列を生成。
  3. INDIRECT関数で数式の中で計算したり範囲に使用したりできる値に変換
  4. 上の過程で指定された範囲内で、VLOOKUP関数を使ってC列の商品の値段を検索
  5. VLOOKUP関数での参照の型を0にして、商品名が合致しないときはエラーを返させる



VLOOKUP関数に適用する検索範囲の起点を設定してみましょう。

B2の値を、A1:L1列の範囲から検索します。ここで、範囲をH1:L1と設定しないことが重要です。H1からにしてしまうとADDRESS関数に当てはめたとき正確なアドレスが生成されません。
MATCH関数の照合の型は、0に
設定します。0:検査値と完全に一致 1:検査値を超えない最大値 -1:検査値を超える最小値
これで、何列目を参照するかが設定されます。
MATCH(B2;$A$1:$L$1;0)

行は1行目ときまっているので1を入れてADDRESS関数に当てはめます。
ADDRESS(1;MATCH(B2;$A$1:$L$1;0))

ADDRESS関数で得られた値をそのままINDIRECT関数に当てはめます。
INDIRECT(ADDRESS(1;MATCH(B2;$A$1:$L$1;0)))



次に、VLOOKUP関数に適用する検索範囲の終点を設定してみましょう。

基本的に、起点と同じです。

まず、列は
MATCH(B2;$A$1:$L$1;0)で起点の列が得られるのでその右隣の列ということで1を加えます。
MATCH(B2;$A$1:$L$1;0)+1

さらに行は、4行目で終了なので4を入れてADDRESS関数に当てはめます。
ADDRESS(4;MATCH(B2;$A$1:$L$1;0)+1)

ADDRESS関数で得られた値をそのままINDIRECT関数に当てはめます。
INDIRECT(ADDRESS(4;MATCH(B2;$A$1:$L$1;0)+1))

これで、起点と終点が設定されたので、
=VLOOKUP(C2;INDIRECT(ADDRESS(1;MATCH(B2;$A$1:$L$1;0))):INDIRECT(ADDRESS(4;MATCH(B2;$A$1:$L$1;0)+1));2)



もっと融通が利く表を作るには

この表は、欠点が1つあります。
一般向けも会員向けも商品のアイテム数が異なると正しく検索されないことです。たとえば会員限定のアイテムを書き加えたとき、単価が反映されません。
これを解消するためには、終点の設定で、ADDRESS関数に入れた4を関数に書き換える必要があります。

COUNTA(INDIRECT(ADDRESS(1;MATCH(B2;$A$1:$L$1;0))):INDIRECT(ADDRESS(100;MATCH(B2;$A$1:$L$1;0))))
これで、B2をA:L列で検索したとき該当した列で、何個、空白ではないセルがあるかが数えられます。
其処セルの値がそのまま、終点アドレスの行番号になります。
ADDRESS(COUNTA(INDIRECT(ADDRESS(1;MATCH(B2;$A$1:$L$1;0))):INDIRECT(ADDRESS(100;MATCH(B2;$A$1:$L$1;0))));MATCH(B2;$A$1:$L$1;0)+1)
これをさらにINDIRECT関数でくくって完成です。
ここに表示したいのですが、余りにも長いためか、はてなのブログでは受け付けてくれません。
仕方なく、画像とサンプルファイルで参照願うことになりました。よろしくお願いします。
このサンプルファイルでは、早見優子さんにだけこの長い数式を適用しています。商品名と単価を適当に追加してその商品名をC列に入力してみてください。
早見優子さんの欄に返される値と、ほかの人に返される値の違いを確認していただくと違いが分かると思います。おそらく早見さん以外はエラーが返されるはずです。



使用している主な関数関数名:ADDRESS関数
書式:=ADDRESS(行番号;列番号;種類;A1;シート名)
何ができる:範囲の中で行番号と列番号が交差するセルのアドレスを文字列として返す
平たく書くと:=ADDRESS(3;1)で$A$3セルが返されます。
●ADDRESS関数で指定する種類と返される値:
種類を省略すると絶対参照・・・$A$3
種類を1に設定すると絶対参照・・・$A$3
種類を2に設定すると相対参照・・・A$3(行を固定)
種類を3に設定すると相対参照・・・$A3(列を固定)
種類を4に設定すると参照なし・・・A3
シート名は、関数を入力するシートと異なるシートへ参照する場合以外、入力不要。

関数名:INDIRECT関数
書式:=INDIRECT(参照範囲)
何ができる:文字列として入力されたセル番号や範囲を計算式で利用できるようにする
平たく書くと:=INDIRECT(A3)でA3セルを参照範囲として計算式の中で利用できるようにします。

関数名:MATCH関数
書式:=MATCH(検索する値;範囲;タイプ)
何ができる:検索する値が、範囲の中で何行目(何列目)にあるかを返す
平たく書くと:=MATCH("ABC";A7:F7;0)で、A7:F7の間で何列目にABCが入力されているかが返されます。

関数名:INDEX関数
書式:=INDEX(範囲;行番号;列番号)
何ができる:範囲の中で行番号と列番号が交差するセルにある値を返す
平たく書くと:=INDEX(A1:G6;3;2) でB3セルにある値が返されます。

この記事をクリップ!