平成29年度秋期基本情報技術者_表計算のマクロをExcelVBAで再現する
目次
1.出典
2.問題で使用するExcelシート「ログ」「アクセス先集計」のダミーデータの簡単な作り方
3.問題文の要旨
4.問題文(疑似言語)
5.解答群(疑似言語)
6.問題文(VBA翻訳)
7.VBA翻訳の補足説明
8.解答群(VBA翻訳)
9.正解
10.正解を入れたVBA完全版 ※動作確認済み
11.2次元配列バージョン ※動作確認済み
12.バックナンバー
13.ExcelVBA講座ご紹介
1.出典
経済産業省国家試験(IPA情報処理推進機構)
平成29年度秋期 基本情報技術者試験 午後試験 選択問題 問13表計算設問3[解答欄d~f]
なお、試験問題及び正解の著作権はIPA情報処理推進機構に帰属します。
2.問題で使用するExcelシート「ログ」「アクセス先集計」のダミーデータの簡単な作り方
シート「ログ」
・セルC2以降:
="http://"&REPT(CHAR(INT(RAND()*26+97)),3)&".co.jp/index.html"
・その他の列はマクロとは無関係なので空白でも良い。
・ただし、C列はRand()を使ってダミーのデータを入力しているので値の貼り付けをして数式を消しておくこと。
シート「アクセス先集計」
・1行目を見出しとして、A2:B9999はあらかじめ空白にしておく。
3.問題文の要旨
社内から社外へのアクセスを調べるため、サーバのログをワークシート「ログ」に保存した。ただし、ログのデータは最大9998件までとする。アクセス先のURLごとのアクセス回数を求めるマクロPage_countを作成して、ワークシート「アクセス先集計」のB2以降に出力したい。
4.問題文(疑似言語)
[マクロ:Page_count]
〇マクロ:Page_count
〇数値型:log_line, count_line
〇文字列型:log_url, count_url
・log_line ← 1
■ 相対(ログ!A1, log_line, 2) <> null
|・count_line ← 1
|・log_url ← 相対(ログ!A1, log_line, 2)
|・count_url ← 相対(A1, count_line, 0)
|■ [ 解答欄d ]
||・count_line ← count_line + 1
||・count_url ← 相対(A1, count_line, 0)
|■
|▲ [ 解答欄e ]
||・相対(A1, count_line, 0) ← log_url
||・相対(A1, count_line, 1) ← 1
|+-----
||・[ 解答欄f ]
|▼
|・log_line ← log_line + 1
■
5.解答群(疑似言語)
dに関する解答群
ア 論理積(count_url = null, count_url = log_url)
イ 論理積(count_url = null, count_url <> log_url)
ウ 論理積(count_url <> null, count_url <> log_url)
エ 論理和(count_url = null, count_url = log_url)
オ 論理和(count_url = null, count_url <> log_url)
カ 論理和(count_url <> null, count_url <> log_url)
eに関する解答群
ア count_url = log_url
イ count_url = null
ウ count_url <> null
エ log_url = null
オ log_url <> null
fに関する解答群
ア 相対(A1, count_line, 1) ← 相対(A1, count_line, 1) + 1
イ 相対(A1, count_line, 1) ← 相対(ログ!A1, log_line, 2)
ウ 相対(A1, count_line, 2) ← 相対(A1, count_line, 2) + 1
エ 相対(A1, count_line, 2) ← 相対(ログ!A1, log_line, 2)
オ 相対(A1, log_line, 1) ← 相対(A1, log_line, 1) + 1
カ 相対(A1, log_line, 1) ← 相対(A1, log_line, 2) + 1
6.問題文(VBA翻訳)
Sub Page_count()
Dim log_line As Integer, count_line As Integer
Dim log_url As String, count_url As String
log_line = 1
Do While Sheets("ログ").Range("A1").Offset(log_line, 2) <> ""
count_line = 1
log_url = Sheets("ログ").Range("A1").Offset(log_line, 2)
count_url = Range("A1").Offset(count_line, 0)
Do While [ 解答欄d ]
count_line = count_line + 1
count_url = Range("A1").Offset(count_line, 0)
Loop
If [ 解答欄e ] Then
Range("A1").Offset(count_line, 0) = log_url
Range("A1").Offset(count_line, 1) = 1
Else
[ 解答欄f ]
End If
log_line = log_line + 1
Loop
End Sub
7.VBA翻訳の補足説明
「相対(A1, 」は「Range("A1").Offset(」と訳します。
「相対(ログ!A1, 」は「Sheets("ログ").Range("A1").Offset(」と訳します。
8.解答群(VBA翻訳)
dに関する解答群
ア count_url = "" And count_url = log_url
イ count_url = "" And count_url <> log_url
ウ count_url <> "" And count_url <> log_url
エ count_url = "" Or count_url = log_url
オ count_url = "" Or count_url <> log_url
カ count_url <> "" Or count_url <> log_url
eに関する解答群
ア count_url = log_url
イ count_url = ""
ウ count_url <> ""
エ log_url = ""
オ log_url <> ""
fに関する解答群
ア Range("A1").Offset(count_line, 1) ← Range("A1").Offset(count_line, 1) + 1
イ Range("A1").Offset(count_line, 1) ← Sheets("ログ").Range("A1").Offset(log_line, 2)
ウ Range("A1").Offset(count_line, 2) ← Range("A1").Offset(count_line, 2) + 1
エ Range("A1").Offset(count_line, 2) ← Sheets("ログ").Range("A1").Offset(log_line, 2)
オ Range("A1").Offset(log_line, 1) ← Range("A1").Offset(log_line, 1) + 1
カ Range("A1").Offset(log_line, 1) ← Range("A1").Offset(log_line, 2) + 1
9.正解
d ウ
基本的に作業する行を次に進めるのは空白でない場合であり「Do while ~ <> ""」は基本形。count_lineをインクリメントしているので、一致するURLを探しているのは明らか。つまり、次の行に進む条件はさらに不一致の場合に限られる(And)。
e イ
アクセス回数に1を入れるのは見つからなかった場合なので、count_urlは空白。
f ア
見つかったのだから、アクセス回数をインクリメントすればよい。
10.正解を入れたVBA完全版 ※動作確認済み
Sub Page_count()
Dim log_line As Integer, count_line As Integer
Dim log_url As String, count_url As String
log_line = 1
Do While Sheets("ログ").Range("A1").Offset(log_line, 2) <> ""
count_line = 1
log_url = Sheets("ログ").Range("A1").Offset(log_line, 2)
count_url = Range("A1").Offset(count_line, 0)
Do While count_url <> "" And count_url <> log_url
count_line = count_line + 1
count_url = Range("A1").Offset(count_line, 0)
Loop
If count_url = "" Then
Range("A1").Offset(count_line, 0) = log_url
Range("A1").Offset(count_line, 1) = 1
Else
Range("A1").Offset(count_line, 1) = Range("A1").Offset(count_line, 1) + 1
End If
log_line = log_line + 1
Loop
End Sub
11.2次元配列バージョン ※動作確認済み
問題の趣旨を変えないまま2次元配列に置き換えてみました。
Sub Page_count()
Dim a(1 To 9998, 1 To 2)
log_url = Sheets("ログ").Range("C2").Resize(9998, 1)
log_line = 1
count_line_max = 1
Do While log_url(log_line, 1) <> ""
count_line = 1
count_url = a(count_line, 1)
Do While count_url <> "" And count_url <> log_url(log_line, 1)
count_line = count_line + 1
If count_line_max < count_line Then count_line_max = count_line
count_url = a(count_line, 1)
Loop
If count_url = "" Then
a(count_line, 1) = log_url(log_line, 1)
a(count_line, 2) = 1
Else
a(count_line, 2) = a(count_line, 2) + 1
End If
log_line = log_line + 1
Loop
Range("A2").Resize(count_line_max, 2) = a
End Sub
12.バックナンバー
13.ExcelVBA講座ご紹介
この記事が気に入ったらサポートをしてみませんか?