理系母の趣味はプログラミング

理系院卒、メーカー技術職の二児の母が、PythonやVBAで色々と作ってアップしていくブログです。

【VBA】検索して、コピペする作業を効率化するマクロを作ってみた。

仕事で、大量のデータから必要なカラムだけ取り出すという単純作業をすることがあります。
このカラムが数列だったらいいのですが、
何十列もあったりするとかなり面倒ですし、ミスも起きかねません。
そこで、マクロをつくりました。

Option Explicit
Option Base 1
Sub Search_Copy_Paste()

Dim KeyRange, SearchRange As Range
Dim ResultArray() As Variant                          '検索結果を格納する配列
Dim KeyArray() As Variant                              '元データを格納する配列
Dim SearchArray() As Variant                         '検索先のデータを格納する配列
Dim keyColnum, SearchRownum As Long     '行数と列数
Dim i, j, k As Long                                           'ループ変数

    
    On Error Resume Next
    Set KeyRange = Application.InputBox(prompt:="検索するカラム名を選択してください", Title:="セルの指定", Type:=8)
    If KeyRange Is Nothing Then Exit Sub
    KeyArray = KeyRange.Value
    
    Set SearchRange = Application.InputBox(prompt:="検索対象の範囲を選択してください", Title:="セルの指定", Type:=8)
    If SearchRange Is Nothing Then Exit Sub
    SearchArray = SearchRange.Value
    
    keyColnum = UBound(KeyArray, 2)
    SearchRownum = UBound(SearchArray, 1)
    
    ReDim ResultArray(SearchRownum, keyColnum)
    
    For i = 1 To keyColnum
        
        ResultArray(1, i) = KeyArray(1, i)
        
        For j = 1 To UBound(SearchArray, 2)
            If ResultArray(1, i) = SearchArray(1, j) Then
                For k = 2 To SearchRownum
                    ResultArray(k, i) = SearchArray(k, j)
                Next k
                Exit For
            End If
        Next j
        
    Next i
    
    With KeyRange.Worksheet
    
    Worksheets.Add
    Range(Cells(1, 1), Cells(SearchRownum, keyColnum)).Value = ResultArray
    MsgBox (ActiveSheet.Name & "に転記しました")
    
    End With
    
End Sub

【基本情報技術者試験】出題形式が大幅変更された午後試験をCBT方式で受験してきた結果と所感【令和2年度秋期】

こんにちは、
先日、基本情報技術者試験の午前試験を受けてきました。
午前試験から1カ月以上開けての受験。

そして何より、今回の午後試験は色々と新形式になっております。
そこで、「旧形式の過去問で対策しているけど、本番はどうなるの?」という人に向けて結果と所感をお伝えできればと思います。

【結果】
93点(午後試験のスコアレポートの正答率×配点で計算しています)
スコアレポートは下記

f:id:kanafuu:20210329094514j:plain
午後試験のスコアレポート(念のため、分野は隠しています。)

ちなみに午前試験のスコアレポートはこちらの記事に記載しています。
kanappphateshakitto.hateblo.jp

問題の選択をミスってなければ合格していると思います。
やったね☆

<CBT方式の所感>
午前試験ではメリットも多かったCBT方式ですが、
午後試験ではデメリットが大きいと感じました。
紙と比較したCBT形式のメリット・デメリットを下記にまとめます。

【メリット】
マークシートを塗りつぶさない為、問題番号と解答のずれが生じにくい→マーク箇所のずれによる大量失点、塗りなおしの為の時間の浪費が防げる。
・解答済/未解答が表示される。→解き忘れがない。
・問題番号をクリックするだけで問題にとべる→後で見返しやすい

【デメリット】
・問題文や図中、選択肢中に書き込めない→解きにくい!
・問題中の表やコードと選択肢を照らし合わせるのにページを何度もスクロールしなければならない。

書き込めないのは事前に覚悟していたのですが、思いがけずスクロールが面倒でした。
特に表計算はセル中の式の空欄に選択肢を当てはめる系の問題が多いので、
例えば、セルE2ってどこをさしてるんだっけ?みたいな確認が多く、選択肢と表を何度も行ったり来たり。
それもあってか、いつもは25分ほどで解ける表計算に35分ほどかかってしまいました。
試験開始の最初に表計算を解いたのでここで少し焦りました。

<新しい出題形式の所感>
令和2年度秋期から、選択問題の出題形式が大幅に変更されました。

(旧)問2~問7から4問選ぶ
(新)問2~問5から2問選ぶ

過去問は旧形式のものしかなかったので、いくら過去問を解いても、本番まで一抹の不安がありました。
しかし、本番を終えて、確信しました。

午後試験が簡単になったと!

私個人の感想ですが、単純に2問分減って時間に余裕ができました。
選択問題の配点は12点から15点に増えているので、3点分のボリュームアップはあったのかな。
情報セキュリティも配点が12点から20点に増えているので、ボリュームアップしたはずですが、
全部解き終えて残り時間を見ると、残り40分…!?
しかも途中から時間に余裕があることがわかって、時間をかけて丁寧に解いていたにも関わらずです。

旧形式過去問で対策していた時は、早くトレースする練習をしたり、問題を解く順番を得意なものからにしたりと、時間内に解くための対策をしていました。
しかし、終わってみると、あれれ?って感じです。

旧形式の過去問で時間内に解けるようであれば、新形式ではよっぽど大丈夫だと思います。


最後に、1歳の娘と2カ月の息子がいるのに、快く試験に送り出してくれた夫に感謝です。

以上、結果と所感でした。
参考になればうれしいです!


「追記」合格していました!実際の午後点数は94点でした。

f:id:kanafuu:20210523153952j:plain

次はPythonに本腰いれたいです。

【FE】基本情報技術者試験、表計算の関数出題頻度を調べてみた。

表計算の過去問を解いていると、よく出てくる関数と、出てこない関数があるな~と思ったので
過去10年分の過去問から、関数の出題頻度を調べてみました。

表計算の問題で関数が出てくる場合、空欄になにが入るかを選択肢から選ぶ形式なので、
その選択肢、または空欄の前後に登場した回数を関数別にカウントしています。(出題に関与しているものだけ調べたかったため)
例えば下記の場合は、IF、論理積論理和に1をカウントします。

f:id:kanafuu:20210217225134p:plain
令和元年秋期問13設問1(a)

同じ年度でも、例えば設問1と設問2で出てきた場合は、2回とカウントしています。

結果は下のグラフにまとめています。

f:id:kanafuu:20210216145225p:plain
表計算関数出題回数

これより、以下のことが考えられます。

1. 関数の出題頻度は均等ではなく、最多のIFで42回、最少は0回である。
2. 最もよく出てくる関数はIFであり、過去10年間では毎回出題に関与している。
3. 論理積論理和、相対、表引き、照合一致、水平照合、垂直照合、照合検索もよく出る。
4. 過去10年間で、一度も出題に関与していない関数が複数ある。

出題頻度の高い関数については説明を見る時間を短縮すべく、使い方を頭に入れておいた方がよさそうです。
特に、照合一致、水平照合、垂直照合、照合検索は使い方が似ていて、選択肢として一緒に出てくることが多いです。

また、ほとんど出題されない関数もあるので、試験まで時間がなければ(あくまで試験対策だけを考えれば)特に覚える必要はなさそうです。
万が一出てきたら、その時は説明を見にいけばいいかと思われます。

こんなことしてないで私も試験勉強します。
以上、表計算の試験対策をしている方の参考になればうれしいです。

基本情報技術者試験をCBT形式で受けてきた所感(午前試験)

先日、コロナによる二度の試験中止を経て、ついに、基本情報技術者試験の午前試験を受けてきました。
1月に出産し、産後0ヵ月でしたが、今受けとかないと、今後もっと大変になる気がしたので、気合で受けました!
今回が初のCBT形式ということで、前情報が少ない中での本番となりましたが、午前試験は8割とれました。

f:id:kanafuu:20210211231123j:plain
午前試験スコアレポート

授乳中に過去問道場解きまくったのがよかったのかな。

個人の感想としては、午前試験においては、紙で解くのと比べて多少の不便はありましたが、メリットもありました。
紙と比較したCBT形式のメリット・デメリットを下記にまとめます。

【メリット】
マークシートを塗りつぶす手間が省ける→時間短縮
マークシートを塗りつぶさない為、問題番号と解答のずれが生じにくい→マーク箇所のずれによる大量失点、塗りなおしの為の時間の浪費が防げる。
・問題にフラグを付けることが出来る。→後で見返しやすい。
・解答済/未解答が表示される。→解き忘れがない。
・問題番号をクリックするだけで問題にとべる→後で見返しやすい

【デメリット】
・問題文や選択肢中に書き込めない→解きにくい。後で見返したときに選んだ根拠がわかりにくい。見返しづらい。
・図中に書き込めない→解きにくい。

以上です。
個人的にはメリットの方が大きいです。(あくまで午前試験においてですが…。)
ただ、CBT形式の操作方法は、予習していったほうがいいです。
問題文中にマーカーをつける機能があるのですが、私は操作方法の予習をしていなかったので本番中に初めて使えることに気づきました。
他にも、問題の一覧表示機能など、使えるものは把握していったほうがいいです。
下記リンク先(プロメトリックのHP)にFE試験の当日の流れと操作方法が記載されています。
pf.prometric-jp.com

午後試験の直前に、一通り読んでいこうと思います。

鬼門は午後試験。
まだ少し時間があるので、育児の隙間時間で勉強したいと思います。
とはいっても0ヵ月と1歳の育児はなかなか忙しくて隙間が…狭い!

頑張るぞ!

基本情報技術者試験の勉強を再開します

こんにちは。

出産予定日まであと3週間を切りました。
正期産です。

Pythonの勉強をぼちぼち続けていたのですが、
産まれたらゆっくりPCに向かう時間なんて絶対無い!
と思うようになり、やる気がなくなってきました。

ということで、最近は勉強から離れていたのですが
何もすることがないとYoutubeとかだらだら見てしまって
暇~な日々が続いていたので、
中断していた基本情報技術者試験の勉強を再開します。
(コロナで過去二回申し込んで二回とも中止になったこともあり、モチベーション下がっていました…。)

午前試験と午後試験があるのですが、
午前試験問題は一問一答形式で、一問につき1、2分で解けるため、Pythonよりは産まれてからも隙間時間でできるだろうと思いました。

午後試験問題が難しいのですが、本番1か月前ぐらいから集中的に取り組む予定です。
(一問が重くて、相当やる気がないと取り組めない…!)

ちょっとはパソコンのこと詳しくなれるはず!

それでは、また^^

【Python】年齢付き年表作成ツールを作ってみた

こんにちは。

家族が増えて、そろそろライフプランを考えなきゃなーと思い、
エクセルでライフプラン表を作ってみたりしてます。

そんなときに使えるかもしれない、年齢付き年表自動作成ツールをpythonで作りました。

こんなウィンドウがでてきて、名前と生年月日を入力します。

f:id:kanafuu:20201218162118p:plain
年表に記載する人の名前と生年月日を入力する画面

OK押すとエクセルで年表が作成され、下記のメッセージが出ます。

f:id:kanafuu:20201218162304p:plain
作成完了のお知らせウィンドウ

同じフォルダに「(入力した名前)'s_life_planning」というファイル名の下記のようなエクセルファイルが作成されました。

f:id:kanafuu:20201218162637p:plain
年表

これが100歳まで横にダーッと続いてます。

以下使い方。

OpenpyxlとかPysimpleGUIとか使ってますので、
あらかじめコマンドプロンプトで下記のpip installしてから使います。

pip install openpyxl
pip install python-dateutil
pip install pysimplegui


以下Pythonコードです。
ファイルはツール起動用とGUI用で別々に2つ作りましたので、
下記二つのPythonファイルを同じフォルダにおいてください。


①life_planning.py (起動用pythonファイル)

from datetime import date
import openpyxl
from dateutil.relativedelta import relativedelta
from openpyxl.utils import get_column_letter
from openpyxl.styles.alignment import Alignment
from openpyxl.styles.borders import Border, Side
import PySimpleGUI as sg
import GUI_InputUserInfo

def main():

    #ユーザーからの入力
    GUI_InputUserInfo.inputwindow()   #実行

    name = GUI_InputUserInfo.name
    b_year = GUI_InputUserInfo.b_year
    b_month = GUI_InputUserInfo.b_month
    b_day = GUI_InputUserInfo.b_day

    birthday = []
    for i in range(0,len(name)):
        birthday.append(date(b_year[i],b_month[i],b_day[i]))

    #年表作成処理
    wb = openpyxl.Workbook()
    sheet = wb.active
    sheet.title = 'life_planning'

    #年月を書き込む
    now = date.today()
    month = now.month
    year = now.year
    end_year = b_year[0] + 101 #ユーザーが100歳になるまで

    sheet['A1'] = '西暦'
    sheet['A2'] = '月'

    #西暦と月を書き込む
    cell = sheet['B2']
    column = cell.column
    for y in range(year,end_year):
        cell.offset(-1,0).value = y
        while True:
            cell.value = month
            cell = cell.offset(0,1)
            if month == 12:
                month = 1
                break
            elif y == end_year - 1 and month == b_month[0]: #100歳のお誕生月で終わる
                break
            month += 1

    #名前と現在の年齢を書き込む

    old_datetime = [] #現在の年齢のdatetimeオブジェクトリストを生成する
    famnum = len(name) #ループ終値を取得
    for i in range(famnum):
        old_datetime.append(relativedelta(now,birthday[i]))
        if birthday[i].month == now.month and old_datetime[i].months == 11 : #今月が誕生月で、まだ誕生日を迎えていなかったら
            old = old_datetime[i].years + 1
        else:
            old = old_datetime[i].years
        sheet.cell(column=1,row=i+3).value = name[i]
        sheet.cell(column=2,row=i+3).value = old

    #誕生月が来たらold+1してセルに書き込む
        for c in sheet['2:2']: #月の行を右端までループ
            if c.value == b_month[i]:
                old += 1
                c.offset(i+1,0).value = old #年齢を書き込む

    #ここからエクセルの体裁整え処理
    #列の幅を整える
    for col in sheet.columns:
        column = col[0].column
        sheet.column_dimensions[get_column_letter(column)].width = 4 #とりあえず全部変える
    sheet.column_dimensions['A'].width = 10 #左端の列幅を設定

    #西暦のセルを結合する
    m = 12 - sheet['B2'].value
    year_row = 1 #西暦の行
    stacol = 2
    endcol = stacol + m #最初の年は誕生月始まりのため、endcolを個別設定
    #99歳の年までループ
    for i in range(year,end_year-1):
        sheet.merge_cells(start_row=year_row,start_column=stacol,end_row=year_row,end_column=endcol)
        stacol = endcol+1
        endcol = endcol+12
    #100歳の年は誕生月で終わるため、個別設定
    sheet.merge_cells(start_row=year_row,start_column=stacol,end_row=year_row,end_column=stacol+b_month[0]-1)

    #罫線を付けて左よせする
    side = Side(style='thin', color='000000')
    border = Border(top=side, bottom=side, left=side, right=side)
    alignment = Alignment(horizontal='left')
    # write in sheet
    for row in sheet:
        for cell in row:
            sheet[cell.coordinate].border = border #枠線
            sheet[cell.coordinate].alignment = alignment #左寄せ

    #ウィンドウ枠を固定する
    sheet.freeze_panes = sheet.cell(row=len(name)+3,column=2)
    #ファイルを保存
    filename = name[0] + '\'s_life_planning.xlsx'
    wb.save(filename)

    sg.popup(filename+'が作成されました。\n'
                      'ファイルを開いてライフプランを立てましょう!\n'
                      'ファイルは実行したPythonファイルと同じフォルダにあります')

main()

GUI_InputUserInfo.py (importするので、ファイル名はこの通りにしてください。)

import PySimpleGUI as sg

name = []
b_year = []
b_month = []
b_day = []

def inputwindow():

    #  セクション1 - オプションの設定と標準レイアウト
    sg.theme('Dark Blue 3')

    layout = [
        [sg.Text('あなたが100歳になるまでの年表を作ります\n' \
                          'ほかの人の年齢も年表に記載できます(最大10人)\n'\
                          '名前と生年月日を教えてください。',
                 key='-TEXT-',size=(70,4))],
        [sg.Text('あなたの名前', size=(12,1)), sg.InputText(size=(10,1)),
         sg.Text('生年月日(西暦)', size=(12,1)),
         sg.InputText(size=(7,1)),sg.Text('年', size=(2,1)),
         sg.InputText(size=(7,1)),sg.Text('月', size=(2,1)),
         sg.InputText(size=(7,1)),sg.Text('日', size=(2,1))]]

    for i in range(1,11):
        layout.append([sg.Text('人物'+str(i), size=(12, 1)), sg.InputText(size=(10, 1)),
         sg.Text('生年月日(西暦)', size=(12, 1)),
         sg.InputText(size=(7, 1)), sg.Text('年', size=(2, 1)),
         sg.InputText(size=(7, 1)), sg.Text('月', size=(2, 1)),
         sg.InputText(size=(7, 1)), sg.Text('日', size=(2, 1))])

    layout.append([sg.Submit(button_text='OK')])

    # セクション 2 - ウィンドウの生成
    window = sg.Window('Life_planning', layout)

    # セクション 3 - イベントループ
    while True:
        event, values = window.read()
        window.close()

        if event is None:
            break

        if event == 'OK':
            for i in range(0,44,4):
                if values[i] == '':
                    continue
                name.append(values[i])
                b_year.append(int(values[i+1]))
                b_month.append(int(values[i+2]))
                b_day.append(int(values[i+3]))

            show_message = name,b_year,b_month,b_day
            sg.popup('年表を作成します')


    # セクション 4 - ウィンドウの破棄と終了
    window.close()

以上です。

ちょっとわかりにくくなったので、使い方をまとめると、

1.上記2つのpythonコードをコピーして、pythonファイルを二つ作成し、同じフォルダ内に保存する。(注意:②のpythonファイルは①から読み込むため、ファイル名を「GUI_InputUserInfo.py」とすること)
2.コマンドプロンプトなどで上記の必要なモジュールをpip installする。
3.①life_planning.py を実行する。
4.名前と生年月日を入力する。
5.OK
6.同じフォルダに「(入力した名前)'s_life_planning」という名前のエクセルファイルが作成される。

以上です。

でもこれ需要なさそうですね(笑)

PyQはじめました。

こんにちは。

Pythonを使えるようになって職場復帰後に楽をしたい!って思いはあるのに
なかなかやる気が出ない。

そこで、
PyQというPythonに特化したオンライン学習を始めてみました。

始めたのは実は2020/10/4

1か月ぐらい継続しております。

スクレイピングとか
少しやってみたり。

一か月続けた感想としては

内容は広く浅い。
Pythonってこんなことできるんだ~って
Pythonでできることを知りたい人には向いてるのかなって思います。

私も今のところPythonでできることを浅くでもいいから知りたい人なので
向いてるのかなと。

とりあえずPyQを継続して
Pythonでできることを知ったうえで、
自分で作りたいプログラムを思いつければいいかなと思っています。

ではでは。