【VBA】Excelマクロの基本的な使い方

Excel VBAに関する記事になります。
業務で「複数のExcelファイルから所定のデータを取得し、一つのCSVにまとめる。」というマクロが必要になり、対応した経緯があります。
個人的にExcel VBAは初挑戦で基礎的なことも分からず四苦八苦しましたが、そこで得られた内容をまとめます。

セルの値を取得
ThisWorkbook.Sheets("sample").Range("A1").Value

「マクロを実行しているエクセルファイル」の「sampleシート」から「A1セル」の値を取得する。
という命令文になります。

エクセルファイルを開く・閉じる
Dim App As Object
Dim Wkb As Object

Set App = CreateObject("Excel.Application")
Set Wkb = App.Workbooks.Open(Filename:="sample.xlsx", ReadOnly:=True)

※※※ここで任意の処理を実行※※※

exApp.Quit


値の代入
' ----- その①
Dim App As Object
Set App = CreateObject("Excel.Application")

' ----- その②
Dim Rng As String
Rng = ThisWorkbook.Sheets("sample").Range("A1").Value
  • Setを使う場合(①)と使わない場合(②)がある。Setを使うのは「オブジェクト型で宣言した変数に代入する時」。Setを使わないのはそれ以外。
  • 「オブジェクト型」とはプロパティやメソッドを持つもの。「~As Object」だけがオブジェクト型ではない点に注意。

任意の値を検索
' 検索範囲の指定
Set SearchArea = wsCurrent.Range("A1:Z10")

' 部分一致検索
Set SearchObj1 = SearchArea.Find("Samp", LookAt:=xlPart)
' 完全一致検索
Set SearchObj2 = SearchArea.Find("Samp", LookAt:=xlWhole)

検索の結果、該当するデータがない場合、オブジェクトは「Nothing」になる。その状態で操作するとエラーになる為、検索後は以下のようにデータ有無チェックを実施する事をおすすめする。

If Not SearchObj1 Is Nothing Then
 ※Nothing ではない時だけ処理を実行
End If


文字列の置換
Replace("あいうえお", "お", "を")

引数は「元文字列」「置換対象」「置換後文字列」の順番に指定。

CSV出力
' CSVファイル作成
Open "data.csv" For Output As #1

' ヘッダー出力
Print #1, "郵便番号, 住所, 氏名" _
; "年齢, 性別, 電話番号"

' 任意の値を出力
Print #1, "123-4567, 東京都〇〇区, 試験太郎, 30, 男, 03-1234-5678"

Close #1
  • ヘッダー出力で改行しているがこれは任意。大量のデータを出力する場合などには、コードの可読性を考慮する等して、必要であれば上記の方法で改行が可能。

【Python】DataFrameの操作(2)

PythonのpandasにおけるDataFrame操作でよく使うものをまとめています。
サンプルコードはDataFrame例と照らし合わせながらご覧いただくとイメージしやすいかと思います。

関連記事はこちら
【Python】DataFrameの操作(1)

DataFrame例

california_housing_test_例(欠損値含む)
Google Colaboratory のサンプルデータから上位10件のみを抽出し、一部を欠損値に更新したもの
▼備考
DataFrameの一部を欠損値に更新するためのコードは以下の通り。

import numpy as np
df.loc[4] = np.nan
df.loc[6]['population'] = np.nan
df.loc[7]['longitude'] = np.nan

取得

要素の値と出現数を取得
# 出現した値とその出現数を取得
s = df['housing_median_age'].value_counts()

# 出現した値
s.index

# 出現数
s.values

▼結果

california_housing_test_要素の値と出現数
画像は出現した値とその出現数を取得したもの
▼備考
value_counts の返却値は Series型 であるため、index と values で個別に取得が可能。

重複した行の取得
df.duplicated()

▼結果

california_housing_test_重複行

重複した列の取得
df['housing_median_age'].duplicated()

▼結果

california_housing_test_重複列

欠損値を含むか判定
df.isnull()

▼結果

california_housing_test_欠損値判定
欠損値の要素が「True」になる

列内に欠損値を含むか判定
df.isnull().any()

▼結果

california_housing_test_欠損値・列判定
列内に欠損値が含まれていると「True」になる

行内に欠損値を含むか判定
df.isnull().any(axis=1)

▼結果

california_housing_test_欠損値・行判定
行内に欠損値が含まれていると「True」になる

変更

行名・列名の変更
# 一つずつ変更
df.rename(columns = {'longitude' : 'abcde'}, index={1 : 'ONE'})

# 一括変更
df.rename(columns = {'longitude' : 'abcde', 'latitude' : 'fghij'}, index={1 : 'ONE', 2 : 'TWO'})

# 全ての行名を変更
df.index = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']

# 全ての列名を変更
df.columns = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']

▼結果

california_housing_test_行名・列名変更
画像は一つずつ変更したもの
▼備考
全ての行名・列名の変更は行数、列数が合わないとエラーになる。

【特許】特許と実用新案

イロモノ記事です。

特許と実用新案
番号
審査過程ごとの番号
番号の書式

特許と実用新案

言葉としては聞き覚えがあるかと思います。
どちらも「発明を保護する権利」であることは同じなのですが、厳密には別モノです。代表的なものざっくり紹介します。

保護対象
  • 特許は「物(プログラムを含む)・方法」が対象。
  • 実用新案は「物品の形状、構造又は組合せ」が対象。
  • 例えば、「コンピュータプログラム、計測方法、製造方法等」に対する発明は特許として出願する必要があるが、「日用品の形状、機械の構造、複数品の組合せ」といったアイデアは、特許又は実用新案のいずれでも出願可能である。
権利化までの期間

実用新案の方が早い。

存続期間

実用新案の方が短い。

費用

実用新案の方が高い。

特許・実用新案の番号

特許は番号で管理されています。
しかし、1つの特許に複数の番号が存在します。
なぜ複数あるかというと、

特許は審査過程ごとに採番・管理される。

からです。

審査過程ごとの番号

出願番号

特許出願が特許庁に受理されると付与される番号。

公開番号
  • 公開特許公報
  • 出願から1年6箇月経過した時点で、出願した発明の内容を一般に知らせるために、特許庁が発行する公報(公開公報)に付与される番号。

公表番号
  • 公表特許公報
  • 外国語でされた国際出願について、原則として、優先日から2年6ヶ月後すみやかに、日本語による翻訳文を掲載した公報(公表公報)に付与される番号。

再公表番号
  • 再公表特許公報
  • 日本語でされた国際出願について、国際公開パンフレットをもとに、その内容を掲載した公報(再公表公報)に付与される番号。

公告番号
  • 公告特許公報
  • 出願公告の決定がされた特許出願及び実用新案登録出願について、その書誌事項、明細書、図面を掲載した公報(公告公報)に付与される番号。平成6年1月以降CD-ROMで発行されていたが、出願公告制度の廃止に伴い、平成8年4月以降発行していない。

特許登録番号
  • 特許登録公報、特許公報、特許掲載公報
  • 特許された発明に付与される番号。

実用新案登録番号
  • 公開実用新案公報
  • 平成5年12月31日以前に出願され、審査官による実体審査を経て実用新案登録された公報(実用新案登録)に付与される番号。

登録実用新案番号
  • 登録実用新案公報
  • 平成6年1月1日以降に出願され、実体的な審査を経ずに実用新案登録された公報(登録実用新案)に付与される番号。

番号の書式

番号種別 書式
特許 実用新案
出願番号 特願元号YY-NNNNNN 実願元号YY-NNNNNN
特願YYYY-NNNNNN 実願YYYY-NNNNNN
公開番号 特開元号YY-NNNNNN 実開元号YY-NNNNNN
特開YYYY-NNNNNN 実開YYYY-NNNNNN
A-YYNNNNNN U-YYNNNNNN
公表番号 特表元号YY-NNNNNN 実表元号YY-NNNNNN
特表YYYY-NNNNNN 実表YYYY-NNNNNN
T-YYNNNNNN TU-YYNNNNNN
再公表番号 WOYY/NNNNNN WOYY/NNNNNN
S-YYNNNNNN SU-YYNNNNNN
公告番号 特公元号YY-NNNNNN 実公元号YY-NNNNNN
特公YYYY-NNNNNN 実公YYYY-NNNNNN
B-YYNNNNNN Y-YYNNNNNN
特許登録番号 特許第NNNNNNN号
特許-NNNNNNN
特登NNNNNNN
B9-NNNNNNNN
実用新案登録番号 実登NNNNNNN
Y9-NNNNNNNN
登録実用新案番号 登実NNNNNNN
U9-NNNNNNNN

【特許】特許とは?特許調査とは?

イロモノ記事です。

はじめに

私はIT関連の会社に勤めており、ソフトウェア開発等が主な業務です。
しかし、ある日、携わることになった業務が、

特許


…は???

そんな右も左もわからぬ状況で書籍やGoogle先生から得た特許知識を「超・ざっくり」まとめた内容になります。
私と同じような被害者…困っている人の付け焼刃にでもなれば幸いです。
尚、何らかの問題が生じても一切の責任を負いかねます。

特許とは?

早速ですが、みんな大好きWikipediaを見てみましょう。

wikipedia_特許
分かるような分からないような。明日には忘れていそうです。
かみ砕くと、

「お前の発明したもの、他に無いものだからしばらく独占して金稼ぎしてもいいよ。」

です。

特許の重要ポイント

たくさんありますが、私が業務上で意識する事になった点から一部を紹介します。

1. 今までにない発明でなければならない。(新規性:特許法第29条1項)
2. 簡単に思いつく発明でないこと。(進歩性:特許法第29条2項)

それぞれ括弧内の言葉で呼称され、特許法で定められています。
尚、2についてですが、例えば「木材の椅子の強度を上げる為、素材を鉄にする」というのはNGです。素材を変えれば強度が上がることは誰でも簡単に思いつきます。
ただし「素材とする鉄の加工方法」という観点に変えると特許権を得られるかもしれません。

特許を得るには?

特許庁に出願します。
…すみません。携わった業務ではこの後の「特許調査」がメインだったので「特許出願」については割愛します。
まったく知らないという事でもないので、その内追記するかもしれません。

実際の特許文書は?

「特許情報プラットフォーム J-PlatPat」というサービスがあります。
会員登録なども不要で、誰でも閲覧できます。
試しに、出願人を「Google」として検索すると以下のような結果が得られました。

jplatpat検索窓
ヘッダー ⇒ 特許・実用新案 ⇒ 特許・実用新案検索 と進んだ画面で検索可能
jplatpat_検索結果
検索結果(2020年12月現在)

特許調査とは?

特許権は得る前も、得た後も、手間が掛かります。その一つが「特許調査」です。
また、一口に「特許調査」といっても目的によって内容が幾つかに分けられます。
ここでは以下の4種について紹介します。

出願前調査
  • 出願内容=どんな発明にするか?を検討する際の調査のこと。また、その発明と同じようなアイデアが先に出願・登録されていないかを調査する。
  • 「先行技術調査」とも呼ばれる。
無効資料調査
  • 自分の発明を出願する時または特許権を得た後に、「邪魔になる他社特許」があった場合、これを無効化する為の資料を探し出す調査。
  • 無効化する為の資料は学術論文や雑誌記事などの「非特許文献」でもOK。
技術動向調査
  • 関心ある分野の最新技術や、競合他社がどのような研究開発に注力しているかなどをチェックする調査のこと。
  • 毎週/毎月ぐらいのペースで文献を継続的に入手して定期的にチェックする。
  • 定期的に文献を配信するサービスを「SDIサービス」という。
侵害予防調査
  • 自社の商品が他社の特許を侵害する可能性がないかを確かめる調査のこと。
  • 「クリアランス調査」「FTO調査」とも呼ばれる。

【Python】DataFrameの操作(1)

PythonのpandasにおけるDataFrame操作でよく使うものをまとめています。
サンプルコードはDataFrame例と照らし合わせながらご覧いただくとイメージしやすいかと思います。

DataFrame例

california_housing_test_head10
Google Colaboratory のサンプルデータから上位10件のみを抽出

データの抽出

df[0:1]

df[:1]

df.iloc[1]

▼結果

california_housing_test_行
▼備考
どの方法でも同じデータが取得できる。ただし、1番目・2番目はDataFrame型、3番目はSeries型になる点に注意。

df['longitude']

df.loc[:, ['longitude', 'total_bedrooms']]

▼結果

california_housing_test_列

任意条件
# housing_median_age列が「15.0」
df[df['housing_median_age'] == 15.0]

▼結果

california_housing_test_単一条件

以下の方法でも上記と同様の処理が可能。複数条件も指定できる。

df[df['housing_median_age'].isin([15.0, 19.0])]

▼結果

california_housing_test_isin

AND条件
# housing_median_age列が「40.0以上」 かつ total_rooms列が「1500.0未満」
df[(df['housing_median_age'] >= 40.0) & (df['total_rooms'] < 1500.0)]

▼結果

california_housing_test_複数条件

OR条件
# housing_median_age列が「40.0以上」 または total_rooms列が「1500.0未満」
df[(df['housing_median_age'] >= 40.0) | (df['total_rooms'] < 1500.0)]

▼結果

california_housing_test_OR条件

NOT条件
# housing_median_age列が「27.0以外」(以下、どちらでもOK)
df[~(df['housing_median_age'] == 27.0)]    # ~(チルダ)を使用
df[(df['housing_median_age'] != 27.0)]     # !=を使用

▼結果

california_housing_test_NOT条件

ランダム
# 全量の3割の件数をランダム抽出(実行のたびに異なる結果)
df.sample(frac=0.3)

# 全量の3割の件数をランダム抽出(何度実行しても同じ結果)
df.sample(frac=0.3, random_state=0)

▼結果

california_housing_test_ランダム
▼備考
指定した割合に対する抽出数は小数点以下切り捨てで実行される。 仮に全量が11件に対して、3割を指定した場合、抽出件数は「3件」になる。

行・列数の取得
print('行数:',df.shape[0])
print('列数:',df.shape[1])

▼結果

california_housing_test_行列数

任意のデータを削除

単一行の削除
# 行3を削除
df.drop(3)

▼結果

california_housing_test_行削除
「3行目」ではなく「行3」を削除している点に注意。

複数行の削除
# dfの行3と行5を削除
df.drop([3,5])

▼結果

california_housing_test_複数行削除

列の削除
# housing_median_age列を削除
df.drop("housing_median_age", axis=1)

▼結果

california_housing_test_列削除

任意のデータを追加

単一行の追加
# 行100を追加し、全ての列を「0」で初期化する。
df.loc['100'] = 0
# 行1000を追加し、列を指定の値で初期化する。
df.loc['1000'] = ['-200.01', '35.5', '19.5', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0']

▼結果

california_housing_test_行追加

複数行の追加
# カラム名のリストを準備
col_list = ["longitude", "latitude", "housing_median_age"]
# 追加行のDataFrameを準備
df_add = pd.DataFrame(data = [['-300.03', '32.09', '20.2'],['-400.04', '23.05', '17.4']], columns = col_list)
# 元DataFrameに追加DataFrameを連結
df = df.append(df_add, ignore_index = True)

▼結果

california_housing_test_複数行追加

単一列の追加
# name列を追加して「no_name」で初期化
df['name'] = 'no_name'

▼結果

california_housing_test_列追加

複数列の追加
# name列を追加して「no_name」で初期化、address列を追加して「no_address」で初期化
df.assign(name='no_name', address='no_address')

▼結果

california_housing_test_複数列追加

DataFrameのファイル出力

CSV出力
' DataFrameの1行を1つのcsvファイルに出力
for i in df.index:
    df.iloc[i].to_csv('./sample_data/output/' + str(i) + '.csv')


テキスト出力
' DataFrameの1行を1つのテキストファイルに出力
for i in df.index:
    path = './sample_data/output/' + str(i) + '.txt'
    f = open(path, mode = 'w')
    f.write(str(df['longitude'][i]))
    f.close()

【Python】複数のtxtファイルをDataFrame化&CSVファイル化する方法

Pythonで表題の処理を実現するコード例です。

import glob
import os
import pathlib

import numpy as np
import pandas as pd


# txtファイルの格納フォルダ
input_txt = "./sample/input"
# CSV出力用フォルダ&ファイル名
output_csv = "./sample/output/out.csv"

read_path = pathlib.Path(input_txt)
temp = []
for fname in read_path.glob('*.txt'):
    # ファイルサイズが0のファイルは無視
    if os.path.getsize(str(fname)) <= 0 :
        continue
    f = open(str(fname))
    text = f.read()
    f.close
    temp.append([fname.name, text])

# データフレームに変換
df = pd.DataFrame(np.array(temp))
df.rename(columns={0:'ファイル名', 1:'テキスト'}, inplace=True)

# CSV出力
df.to_csv(output_csv, index=False, encoding='utf_8_sig')

Windows で大容量ファイルを作る

ソフトウェアやサービスの性能試験・負荷試験などにおいて、大容量のファイルが必要になることがあると思います。
数百MB程度ならお持ちのファイルがあると思いますが、数百GBとなるとなかなかお持ちでないケースが多いのではないでしょうか?
そんな時に使える手法です。

指定サイズのファイルを作る
$ fsutil file createnew ファイル名 サイズ
  • サイズの目安は以下の通り。(単位はバイト)
    100GB:107374182400
    500MB:536870912

  • 作成されたファイルの内容は「ゼロデータ」となる。読み込みを行っても「0」しか返らないので注意。