Quantcast
Viewing all articles
Browse latest Browse all 60

数式/関数/パワークエリ:金種を計算する

金種計算(紙幣や硬貨などの通貨の枚数を計算する)については、昔から色んなやり方がありますし、条件を絞れば比較的簡単に計算できます。ただ、金額範囲と通貨範囲を指定してスピルで計算しようとすると、少し面倒になります。

Image may be NSFW.
Clik here to view.

金種自体は「金額を、大きいほうの隣りの通貨(紙幣・硬貨)で割った時の余りを、指定の通貨で割る」ことで求められます。

例:「52,431円」の場合、千円札は何枚必要か
「52,431」を「5千円札(5000)」で割った時の余りは「2,431」 「2,431」を「千円札(1000)」で割った「2.431」の整数部「2」を抜き出す →「千円札は2枚必要」

この計算は「一つ大きい通貨(5000)は、指定の通貨(1000)で必ず割り切れる」ことを利用しています。なので「2千円札」が入ると上手くいきません。「5000」は「2000」では割り切れませんので。

これをスピルで計算する場合、通貨範囲を1列ずらして参照するのに、TAKE・DROP関数を使います。

数式版の金種計算
Image may be NSFW.
Clik here to view.

=LAMBDA(     x,y,INT(HSTACK(x/TAKE(y,,1),MOD(x,DROP(y,,-1))/DROP(y,,1))) )(A2:A4,B1:J1)

これで計算できます。今回は負の値はないものとしているので、整数化には INT関数を使いました。

ついでに同じ計算をパワークエリでもやってみます。

クエリ版の金種計算
Image may be NSFW.
Clik here to view.

let     ソース = テーブル1,     金種リスト1 = {1, 5, 10, 50, 100, 500, 1000, 5000, 10000},     金種リスト2 = List.Zip(         {             List.Skip(金種リスト1)             & {List.Max(ソース[金額])+1}, 金種リスト1         }     ),     計算 = (x)=>         List.Transform(             金種リスト2,             each Number.IntegerDivide(Number.Mod(x, _{0})/_{1}, 1)         ),     金種計算 = List.Transform(         ソース[金額],         each Table.PromoteHeaders(             Table.FromColumns(                 {{"金額", _}}                 & List.Reverse(List.Zip({金種リスト1, 計算(_)}))             )         )     ),     テーブル変換 = Table.Combine(金種計算),     型の変更 = Table.TransformColumnTypes(         テーブル変換,         List.Transform(             {"金額"} & 金種リスト1,             each {Text.From(_), Int64.Type}         )     ) in     型の変更

以上。おまけのつもりなので、クエリについては内容精査していません。あしからず。


Viewing all articles
Browse latest Browse all 60

Trending Articles