名称未設定-2

平成27年度秋期基本情報技術者_表計算のマクロをExcelVBAで再現する

目次

1.出典
2.問題で使用するExcelシート「価格表」「セット値引き表」「購入伝票」の簡単な作り方
3.問題文の要旨
4.問題文(疑似言語)
5.解答群(疑似言語)
6.問題文(VBA翻訳)
7.VBA翻訳の補足説明
8.解答群(VBA翻訳)
9.正解
10.正解を入れたVBA完全版 ※動作確認済み
11.2次元配列バージョン ※動作確認済み
12.バックナンバー
13.ExcelVBA講座ご紹介

1.出典

経済産業省国家試験(IPA情報処理推進機構)
平成30年度秋期 基本情報技術者試験 午後試験 選択問題 問13表計算設問3[解答欄e~g]

なお、試験問題及び正解の著作権はIPA情報処理推進機構に帰属します。

2.問題で使用するExcelシート「価格表」「セット値引き表」「購入伝票」の簡単な作り方

シート「価格表」

シート「セット値引き表」

シート「購入伝票」

商品名を検索値として単価を求めるというとんでもない表である。また、購入内容に同じ商品を2行入力してもよい。

3.問題文の要旨

販売している商品は「価格表」記載の50品目で、1回に購入できる商品は20品目以下とする。セットは「セット値引き表」記載の10種類で、特定の商品を同時に購入すると値引きが適用される。マクロを用いてC30:C39にセット数を求めたい。

4.問題文(疑似言語)

[マクロ:Calc_Discount_Price]
〇マクロ:Calc_Discount_Price
〇数値型:Goods_Num[50], Set_Num, Num, Val, I, J
〇文字列型:Name
■ I: 0, I<=49, 1
|・Name ← [ 解答欄e ]
|・Goods_Num[I] ← 条件付合計(B7:B26, =Name, C7:C26)
■
■ I: 0, I<=9, 1
|・Val ← Goods_Num[相対(セット値引き表!K3, I, 0) - 1] / 相対(セット値引き表!D3, I, 0)
|・Set_Num ← 整数部(Val)
|■ J: 1, J<=2, 1
||・Val ← Goods_Num[相対(セット値引き表!K3, I, J) - 1] / 相対(セット値引き表!D3, I, J * 2)
||・Num ← 整数部(Val)
||▲ [ 解答欄f ]
|||・Set_Num ← Num
||▼
|■
|▲ Set_Num <> 0
||・相対 (C30, I, 0) ← Set_Num
||■ J: 0, J<=2, 1
|||・Goods_Num[相対(セット値引き表!K3, I, J) - 1] ← Goods_Num[相対(セット値引き表!K3, I, J) - 1] - 相対(セット値引き表!D3, I, J * 2)[ 解答欄g ]
||■
|+-----
||・相対 (C30, I, 0) ← null
|▼
■

5.解答群(疑似言語)

eに関する解答群
 ア 価格表!A2
 イ 価格表!B2
 ウ 価格表!C2
 エ 相対(価格表!A2, I, 0)
 オ 相対(価格表!B2, I, 0)
 カ 相対(価格表!C2, I, 0)

fに関する解答群
 ア Num < Set_Num
 イ Num > Set_Num
 ウ Num = 0
 エ Num <> 0
 オ Num <> Set_Num
 カ Set_Num = 0
 キ Set_Num <> 0

gに関する解答群
 ア + 1
 イ + Set_Num
 ウ - 1
 エ - Set_Num
 オ * Set_Num
 カ / Set_Num

6.問題文(VBA翻訳)

Sub Calc_Discount_Price()
    Dim Goods_Num(49) As Integer, Set_Num As Integer, Num As Integer, V As Integer, I As Integer, J As Integer
    Dim N As String
    For I = 0 To 49
        N = [ 解答欄e ]
        Goods_Num(I) = WorksheetFunction.SumIf(Range("B7:B26"), "=" & N, Range("C7:C26"))
    Next
    For I = 0 To 9
        V = Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, 0) - 1) / Sheets("セット値引き表").Range("D3").Offset(I, 0)
        Set_Num = Int(V)
        For J = 1 To 2
            V = Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, J) - 1) / Sheets("セット値引き表").Range("D3").Offset(I, J * 2)
            Num = Int(V)
            If [ 解答欄f ] Then
                Set_Num = Num
            End If
        Next
        If Set_Num <> 0 Then
            Range("C30").Offset(I, 0) = Set_Num
            For J = 0 To 2
                Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, J) - 1) = Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, J) - 1) - Sheets("セット値引き表").Range("D3").Offset(I, J * 2)[ 解答欄g ]
            Next
        Else
            Range("C30").Offset(I, 0) = ""
        End If
    Next
End Sub

7.VBA翻訳の補足説明

「Val」「Name」は予約語なので「V」「N」としています。また、Goods_Num[50]はGoods_num(49)としています。

8.解答群(VBA翻訳)

eに関する解答群

 ア Sheets("価格表").Range("A2")
 イ Sheets("価格表").Range("B2")
 ウ Sheets("価格表").Range("C2")
 エ Sheets("価格表").Range("A2").Offset(I, 0)
 オ Sheets("価格表").Range("B2").Offset(I, 0)
 カ Sheets("価格表").Range("C2").Offset(I, 0)

fに関する解答群

 ア Num < Set_Num
 イ Num > Set_Num
 ウ Num = 0
 エ Num <> 0
 オ Num <> Set_Num
 カ Set_Num = 0
 キ Set_Num <> 0

gに関する解答群

 ア + 1
 イ + Set_Num
 ウ - 1
 エ - Set_Num
 オ * Set_Num
 カ / Set_Num

9.正解

e オ
「Name」ということは商品名(B列)。相対でなければループの意味が無い。
f ア
問題文に「セットにできる最大の数量」とあるのは割り算をしてIntをしている部分の説明。セットが可能な数は最小値を求める。
g オ
注文数量からセットした数量(構成数量*セット数)を引く。

10.正解を入れたVBA完全版 ※動作確認済み

Sub Calc_Discount_Price()
   Dim Goods_Num(49) As Integer, Set_Num As Integer, Num As Integer, V As Integer, I As Integer, J As Integer
   Dim N As String
   For I = 0 To 49
       N = Sheets("価格表").Range("B2").Offset(I, 0)
       Goods_Num(I) = WorksheetFunction.SumIf(Range("B7:B26"), "=" & N, Range("C7:C26"))
   Next
   For I = 0 To 9
       V = Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, 0) - 1) / Sheets("セット値引き表").Range("D3").Offset(I, 0)
       Set_Num = Int(V)
       For J = 1 To 2
           V = Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, J) - 1) / Sheets("セット値引き表").Range("D3").Offset(I, J * 2)
           Num = Int(V)
           If Num < Set_Num Then
               Set_Num = Num
           End If
       Next
       If Set_Num <> 0 Then
           Range("C30").Offset(I, 0) = Set_Num
           For J = 0 To 2
               Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, J) - 1) = Goods_Num(Sheets("セット値引き表").Range("K3").Offset(I, J) - 1) - Sheets("セット値引き表").Range("D3").Offset(I, J * 2) * Set_Num
           Next
       Else
           Range("C30").Offset(I, 0) = ""
       End If
   Next
End Sub

11.2次元配列バージョン ※動作確認済み

問題の趣旨(出題意図)を変えないまま、2次元配列に置き換えてみました。

Sub Calc_Discount_Price()
   Dim Goods_Num(49)
   a = Sheets("セット値引き表").Range("C3:H12")
   b = Sheets("セット値引き表").Range("K3:M12")
   c = Range("B7:C26")
   
   For I = 0 To 49
       N = Sheets("価格表").Range("B2").Offset(I, 0)
       Goods_Num(I) = 0
       For J = 1 To 20
           If c(J, 1) = N Then Goods_Num(I) = Goods_Num(I) + c(J, 2)
       Next
   Next
   For I = 0 To 9
       V = Goods_Num(b(I + 1, 1) - 1) / a(I + 1, 2)
       Set_Num = Int(V)
       For J = 2 To 3
           V = Goods_Num(b(I + 1, J) - 1) / a(I + 1, J * 2)
           Num = Int(V)
           If Num < Set_Num Then
               Set_Num = Num
           End If
       Next
       If Set_Num <> 0 Then
           Range("C30").Offset(I, 0) = Set_Num
           For J = 1 To 3
               tmp = b(I + 1, J) - 1
               Goods_Num(tmp) = Goods_Num(tmp) - a(I + 1, J * 2) * Set_Num
           Next
       Else
           Range("C30").Offset(I, 0) = ""
       End If
   Next
End Sub

12.バックナンバー

13.ExcelVBA講座ご紹介


この記事が気に入ったらサポートをしてみませんか?