m-eye blog

ノンプログラマによるVBAとPythonの学習記録

PythonをVBAと比較しながら覚えようPart2

f:id:m-eye:20181010190201j:plain

 

はじめに

PythonをVBAと比較しながら覚えようのPart2です。

今回は「値」と「演算子」が中心ですね。

 

値の種類

値は、大きく数値、文字列、論理値にわかれます。

 

数値

PythonとVBAでは、あつかうことのできる数値に違いがあります。

 

Pythonにおける数値

Pythonでは、整数型・浮動小数点数型・2進数型・8進数型・16進数型・複素数型の数値を扱うことができます。

数値の型 数値の範囲 説明
整数型 小数点以下がない数値 0と負の数を含む
浮動小数点数型 小数点以下がある数値 0と負の数を含む
2進数型 0と1の数字で表す 0bを先頭につける
8進数型 0〜8の数字で表す 0oを先頭につける
16進数型 0〜9・A〜Fで表す 0xを先頭につける
複素数型 実部+虚部 虚部にはjをつける

ほんとはほかにもありますが、最初はこれでかまわないと思います。

 

整数

整数には正の数と負の数を含みますが、厳密には、マイナスの符号-とプラスの符号+は、それぞれ負の数、正の数を表す演算子です。-3+5という表現も可能です。

 

浮動小数点数

浮動小数点数で、整数部が0、あるいは小数点以下が0のときは、.9910.のように0を省略できます。

また、整数と浮動小数点数との計算結果は、浮動小数点数になります。整数同士の割り算では、割り切れても結果は浮動小数点数になります。

大きな桁数の数値には指数表記も可能です。たとえば、123000001.23e+70.000969.6e-4です。eは大文字でもかまいません。e+7は10の7乗、e-4は10のマイナス4乗です。

 

2進数・8進数・16進数

2進数で0b0101は10進数の5、8進数で0o011は10進数の9、16進数で0xFFは10進数の255を表します。

虚数とは、2乗すると-1のになる、実世界には存在しない想像上の数値(Imaginary Number)の単位です。複素数は虚数部分を含む数値です。人間の想像力はすごいですね。

 

VBAにおける数値

VBAでは、バイト型・整数型・長整数型・単精度浮動小数点型・倍精度浮動小数点型・通貨型・日付型の数値を扱うことができます。

VBAに多くの数値型があって、Pythonのほうが数値型がすくないのは意外ですね。実は、Pythonの組み込み型には数値型がすくないですが、datetimeという標準ライブラリがあって、日付や時間は値の種類ではなく、オブジェクトの種類であり、プロパティ(Pythonではアトリビュート)とメソッドで操作します。

VBAのバイト型・整数型・長整数型が、Pythonの整数型にあたります。

数値の型 数値の範囲 説明
バイト型(Byte) 0〜255 符号なし8ビットの整数
整数型(Integer) -32,768~32,767 長整数型よりも範囲が狭い
長整数型(Long) -2,147,483,648~2,147,483,647 整数型よりも範囲が広い
単精度浮動小数点型(Single) -3.402823E38~-1.401298E-45(負)、1.401298E-45~3.402823E38(正)の範囲 倍精度浮動小数点型よりも範囲が狭い
倍精度浮動小数点型(Double) -1.79769313486232E308~-4.94065645841247E-324(負)、4.94065645841247E-324~1.79769313486232E308(正)の範囲 単精度浮動小数点型よりも範囲が広い
通貨型(Currency) -922,337,203,685,477.5808~922,337,203,685,477.5807 金額を扱う・整数型よりも扱える範囲が広い
日付型(Date) 西暦100年1月1日~西暦9999年12月31日 「1900/1/1 0:00」が内部値「1」となり、1日が「1」ずつ増える値をとる

こうしてみると、VBAではそれぞれの型で扱える範囲をこまかく限定しているのがわかりますね。むかし、PCの性能がよくなかった頃の影響でしょうか。いまではその影響を考える必要がないくらい、PCの性能があがっていますが。

したがって、今では整数型・単精度浮動小数点型を使う積極的な理由はありません。長整数型・倍精度浮動小数点型を使うのがよいでしょう。

 

PythonとVBAの違い

Pythonでは、ふつうの数値にくわえて、2進数・8進数・16進数や複素数があつかえます。いっぽう、VBAでは用途によってこまかく数値の型を変更することができます。

 

演算子

数値や文字の演算に使います。

 

数値演算子

数値演算子も、PythonとVBAとで若干違いがあります。

 

Pythonの数値演算子

演算子 説明
+ a + b 足し算
- a - b 引き算
* a * b 掛け算
/ a / b 割り算
// a // b aをbで割った商の整数値(小数点以下を切り捨て)
% a % b aをbで割って、割り切れなかった余り(剰余)
** a ** n aをn回掛けた値(べき乗)

ここにない演算には、mathモジュールが必要です。

 

VBAの数値演算子

演算子 説明
+ a + b 足し算
- a - b 引き算
* a * b 掛け算
/ a / b 割り算
¥ a ¥ b aをbで割った商の整数値(小数点以下を切り捨て)
Mod a Mod b aをbで割って、割り切れなかった余り(剰余)
^ a ^ n aをn回掛けた値(べき乗)

Modだけが異質ですね。なにか理由があるのでしょうか。

 

文字列

 

シングルクォートとダブルクォート

Pythonでは、文字列をシングルクォートまたはダブルクォートで囲み、'シングルクォート'"ダブルクォート"というように表現します。

VBAでは、文字列をダブルクォートで囲み、"ダブルクォート"というように表現します。

VBAでのシングルクォートは、コメント行の開始を意味しますので、比較しながら覚える場合は注意が必要です。

 

エスケープシーケンス

 

Pythonのエスケープシーケンス

エスケープシーケンス 説明
\n 改行(ラインフィード)
\t 水平タブ
\r キャリッジリターン
\" ダブルクォート
\' シングルクォート
\\ バックスラッシュ

Windowsでは、\¥で表示されます。

 

VBAのエスケープシーケンス

エスケープシーケンス 説明
vbLf 改行(ラインフィード)
vbTab 水平タブ
vbCr キャリッジリターン
vbCrLf キャリッジリターン・ラインフィード
"" ダブルクォート
シングルクォートはふつうにダブルクォートの中に埋め込むことができます
¥¥ 円マーク

 

複数行の文字列

 

Pythonにおける複数行の文字列

クォートを3回つづけて、'''〜'''あるいは"""〜"""のように囲むと、複数行の文字列を作ることができます。

poem = '''すすめの子
そこのけそこのけ
お馬がとおる'''
すすめの子
そこのけそこのけ
お馬がとおる

また、\nを挿入すると、その部分で改行することもできます。

poem = 'すすめの子\nそこのけそこのけ\nお馬がとおる'

 

VBAにおける複数行の文字列

改行したい文字列と文字列を、エスケープシーケンスvbCrLfで連結します。

ただし、セルのなかでは、エスケープシーケンスvbLfで連結します。

Dim Poem As String

'セル以外の場合
Poem = "すずめの子" & vbCrLf & "そこのけそこのけ" & vbCrLf & "お馬がとおる"

'セル内の場合
Poem = "すずめの子" & vbLf & "そこのけそこのけ" & vbLf & "お馬がとおる"
すすめの子
そこのけそこのけ
お馬がとおる

 

文字列の演算子

 

Pythonの文字列の演算子

演算子 説明
+ 'a' + 'b' 文字列abの連結。文字列がabになる
* 'abc' * n 文字列abcをn回繰り返す。nが2ならば、'abcabc'となる
print('a' + 'b')
print('abc' * 2)
ab
abcabc

 

VBAの文字列の演算子

演算子 説明
& "a" & "b" 文字列abの連結。文字列がabになる

VBAには、文字列を繰り返す演算子はありません。しかし、指定した1文字を繰り返すString関数、指定した2文字以上を繰り返すREPT関数、指定した数のスペースからなる文字列を返すSpace関数があります。

MsgBox "a" & "b"
MsgBox String(2, "ABC")
MsgBox WorksheetFunction.Rept("abc", 2)
MsgBox Space(5)
ab
AA
abcabc
     '空白文字が5回繰り返されている

 

数値と文字列を連結する

Pythonでは、数値と文字列を連結したい場合は、あらかじめ明示的に数値を文字列型に変換する必要があります。変換にはstr()を使います。

数値と文字列をそのまま連結するとタイプエラー(TypeError)になります。

VBAでは、数値と文字列をそのまま連結しても問題ありません。VBAが自動的に型変換してくれます。

 

文字の取り出し

id = 'abc123xyz'
print(id[0]) # 先頭から1文字目
print(id[2]) # 先頭から3文字目
print(id[-1]) # 後ろから1文字目
print(id[4:]) # 5文字目から最後まで
print(id[4:4+4]) # 5文字目から4文字
print(id[:-7]) # 後ろから数えて7文字目の手前まで
a
c
z
23xyz
23xy
c123xyz

文字列から文字を取り出すには[]を利用します。文字の位置は1文字目を0と数え、マイナスは後ろから数えます。-1が最後の文字です。

Dim id As String
id = "abc1234xyz"
MsgBox Left(id, 1) '先頭から1文字目
MsgBox Mid(id, 3, 1) '先頭から3文字目
MsgBox Right(id, 1) '後ろから1文字目
MsgBox Mid(id, 5) '5文字目から最後まで
MsgBox Mid(id, 5, 4) '5文字目から4文字
MsgBox Right(id, 7) '後ろから数えて7文字目の手前まで
a
c
z
23xyz
23xy
c123xyz

Pythonでは、文字列を文字の配列としてとらえて文字を取り出していますが、VBAでは、Left関数・Mid関数、Right関数で取り出しています。また、VBAでは文字の位置は1文字目を1と数えています。

 

論理値

論理値は、PythonでもVBAでもTrueFalseです。

Pythonでは、1True0Falseです。

VBAでは、-1True0Falseです。

 

比較演算子

 

Pythonの比較演算子

演算子 説明
== a == b aとbが等しいとき、True
!= a != b aとbが等しくないとき、True
> a > b aがbより大きいとき、True
>= a >= b aがb以上のとき、True
< a < b aがbより小さいとき、True
<= a <= b aがb以下のとき、True

aとbが等しいときは==を使い、等しくないときは!=を使います。

 

VBAの比較演算子

演算子 説明
= a = b aとbが等しいとき、True
<> a <> b aとbが等しくないとき、True
> a > b aがbより大きいとき、True
>= a >= b aがb以上のとき、True
< a < b aがbより小さいとき、True
<= a <= b aがb以下のとき、True

aとbが等しいときは=を使い、等しくないときは<>を使います。

 

右結合・左結合

Pythonの比較演算子には右結合・左結合といった概念がなく、常に両隣の値を比較して、その論理積が式の値となるため、次のような式が可能です。

age = 16
if 13 <= age <= 20:
    print('True')

VBAで同じことをやろうとすると、次のような式になります。

Dim Age As Long
Age = 16
If (13 <= Age) And (Age <= 20) Then
    MsgBox "True"
End If

 

Pythonの論理演算子

Pythonには、andornot、という3つの論理演算子があります。

演算子 説明
and a and b 論理積。aかつbの両方がTrueのときTrue。一方でもFalseならFalse
or a or b 論理和。aまたはbのどちらか一方でもTrueならばTrue。両方ともFalseならばFalse
not not a 否定。aがTrueならばFalse。aがFalseならばTrue
# 論理積
>>> True and True
True

>>> True and False
False

# 論理和
>>> True or True
True

>>> True or False
True

>>> False or False
False

# 否定
>>> not True
False

>>> not False
True

# 変数aが50以上かつ100以下のときTrue
>>> a = 80
>>> (a >= 50) and (a <=100)
True

>>> a = 110
>>> (a >= 50) and (a <=100)
False

>>> a = 'NG' ; b = 'OK'
>>> (a == 'OK') or (b == 'OK')
True

>>> True + False
1

>>> True + True
2

>>> 1 and 1
1

>>> 1 or 0
1

>>> 2 or 3 # 左項を採用
2

>>> 2 and 3 # 右項を採用
3

 

Pythonのビット演算子

ビット演算子は2進数の値をビットごとに演算します。ビット演算ではビットの合成や打ち消し(ビットの立て落とし)ができるので、画像の合成などで活用されます。

 

論理積・論理和・排他的論理和

演算子 説明
& a&b 論理積(AND)。両ビットともに1のとき1
| a|b 論理和(OR)。どちらかのビットが1ならば1
^ a^b 排他的論理和(XOR)。比較したビットの値がことなるとき1
~ ~a ビット反転(NOT)。ビットの10を反転させる

f:id:m-eye:20181027210409p:plain

左シフト・右シフト

演算子 説明
<< a<<1 左シフト。ビットを左にずらす。値は2倍になる
>> a>>1 右シフト。ビットを右にずらす。値は1/2になる

直接の意味としては、コンピュータの処理能力の低かった時代にかけ算・わり算のかわりに高速な左シフト・右シフトをつかったり、ハードウェア寄りの処理をおこなうときに用いたりするのですが、必要にせまられなければ、いまどき使うこともないでしょう。

>>> a = 0b001011
>>> a
11

>>> a << 1 # 左に1桁シフト
22

>>> a = 0b001011
>>> bin(a << 1)
'0b10110'

 

ビットマスク

必要な部分を1にした値とANDする(論理積を求める)ことで必要なビットをぬきだすことができます。

 

下3桁のビットマスク

>>> a = 0b100110
>>> bin(a & 0b111)
'0b110'

 

途中のビットのビットマスク

>>> a = 0b10101
>>> bin((a>>1) & 0b11)
'0b10'

0b101010b1010にしておいて0b11とビットマスク演算をすることで、もとの数値の3桁目と2桁目の10を取り出せます。

 

VBAの論理演算子・ビット演算子

VBAの論理演算子は、ビット演算にもつかいます。

IF文などにつかわれるAndOrNotのつかいかたは簡単ですのでここでは省略します。

VBAのビット演算でいちばんよく使われるのは、ビット落としなどをつうじて、ファイルの属性変更(読み取り専用属性の解除)をおこなうときなどです。

演算子 説明
And a And b 論理積。両ビットともに1のとき1
Or a Or b 論理和。どちらかのビットが1ならば1
Not Not a ビット反転。ビットの10を反転させる
Xor a Xor b 排他的論理和。ビットが一致しないときは1
Eqv a Eqv b 論理等価。ビットが一致するときは1
Imp a Imp b 論理包含。(Not A) Or B

EqvImpはほとんど使われないので、おぼえる必要もないと思います。

?True And True
True

?True And False
False

?True Or True
True

?True Or False
True

?False Or False
False

?Not True
False

?Not False
True

?True + False
-1 

?True + True
-2 

' 数値の論理演算はビット演算になる

?1 and 1
 1 

?1 or 0
 1 

?2 or 3 '"10" or "11" 論理和を求める
 3      '"11"

?2 and 3 '"10" and "11" 論理積を求める
 2       '"10"

なお、VBAで左シフト・右シフトをおこなうときは、BITLSHIFT関数、BITRSHIFT関数をつかいます。

 

型変換

Pythonでは、値の型については最低限のことを知っておけばそれで足ります。

VBAでは、値の型については通常の型以外に、なんでも入るVariant型、総称オブジェクト型のObject型、などについても知っておく必要があります。

VBAでの型変換については、自動キャスト(型変換)がおこなわれるので、あまり意識する必要はないといえます。

 

型を調べる

Pythonでは、値の型はtype()でしらべられます。

>>> type(1)
<class 'int'>

これは数値1の型がint型であることをしめしています。

>>> n = 12.3 ; name = '山田'
>>> type(n)
<class 'float'>

>>> type(name)
<class 'str'>

浮動小数点数の型はfloat、文字列の型はstrです。

 

VBAでは、値の型はTypeName関数やVarType関数でしらべられます。

Dim a As Integer
a = 1
MsgBox TypeName(a)   ' Integer(文字列)を返す
MsgBox VarType(a)    ' 2(vbInteger)を返す

TypeName関数の戻り値

文字列 内容
WorkBook ブック
Worksheet シート
Range セル
Chart グラフ
TextBox テキストボックス(ActiveXコントロール)
Label ラベル(ActiveXコントロール)
CommandButton コマンドボタン
Object オブジェクト
Unknown 種類が不明なオブジェクト
Nothing オブジェクト変数の初期値

VarType関数の戻り値

定数 内容
0 vbEmpty 値(未初期化)
1 vbNull 値(無効な値)
2 vbInteger 整数型
3 vbLong 長整数型(long)
4 vbSingle 単精度浮動小数点数型(Single)
5 vbDouble 倍精度浮動小数点数型(Double)
6 vbCurrency 通貨型(Currency)
7 vbDate 日付型(Date)
8 vbString 文字列型
9 vbObject オートメーションオブジェクト
10 vbError エラー型
11 vbBoolean ブール型(Boolean)
12 vbVariant バリアント型 (Variant) (バリアント型配列にのみ使用)
13 vbDataObject 非オートメーションオブジェクト
17 vbByte バイト型
8192 vbArray 配列(Array)

 

数値を文字列に変換する

数値を文字列と連結しようとするとエラーになりますので、str()をつかって数値を文字列に変換します。

>>> len = 10 * 1.23
>>> ans = '長さ' + str(len) + 'cm'
>>> ans
'長さ12.3cm'

>>> ans = '5<10は' + str(5<10) + 'です。'
>>> ans
'5<10はTrueです。'

VBAではつぎのようにします。

Dim len As Single
len = 10 * 1.23
Dim ans As String
ans = "長さ" & CStr(len) & "cm"
MsgBox ans ' 「長さ12.3cm」を返す

Dim ans As String
ans = "5<10は" & CStr(5 < 10) & "です。"
MsgBox ans '5<10はTrueです。

 

いろいろな型変換

関数名 内容
str() 文字列型への型変換
int() 整数型への型変換
float() 浮動小数点数への型変換
bool() 論理値への型変換
bin() 2進数の文字列に変換
oct() 8進数の文字列に変換
hex() 16進数の文字列に変換
>>> int('250') * 3 # 整数に型変換
750

>>> float('1.5') + 0.2 # 浮動小数点数に型変換
1.7

# 浮動小数点数を整数化すると小数点以下は切り捨てられる
>>> int(12.9) 
12

>>> bin(10)
'0b1010'

>>> oct(10)
'0o12'

>>> hex(10)
'0xa'

VBAの場合はつぎのようになります

関数名 内容
CBool ブール型(Boolean)へのデータ変換
CByte バイト型(Byte)へのデータ変換
CCur 通貨型(Currency)へのデータ変換
CDate 日付型(Date)へのデータ変換
CDbl 倍精度浮動小数点数(Double)へのデータ変換
CInt 整数型(Integer)へのデータ変換
CLng 長整数型(Long)へのデータ変換
CSng 単精度浮動小数点数型(Single)へのデータ変換
CVar バリアント型(Variant)へのデータ変換
CStr 文字列型(String)へのデータ変換
MsgBox CInt("250") * 3 ' 750を表示

MsgBox CSng(1.5) + 0.2 ' 1.7を表示

'浮動小数点数を整数化するときに直接「CInt」関数をつかってはならない
MsgBox CInt(RoundDown(Val("12.9"))

'2進数の数値に変換
'512以上の数値の場合にエラー発生
MsgBox WorksheetFunction.Dec2Bin(10)'1010を表示

'8進数の数値の変換
'-536870912〜536870911の範囲外の数値の場合エラー発生
MsgBox WorksheetFunction.Dec2Oct(10) '12を表示

'16進数の数値に変換
MsgBox WorksheetFunction.Dec2Hex(10)'Aを表示

 

変数

  • 値を一時的に保管する箱のようなもの
  • 箱の中身は変更することができる
  • 変数をつかって式が書ける(実際はこちらの役割のほうが大きい)

 

変数の作成

Pythonの変数には宣言が不要。

値を代入することで変数が作成されます。

=を代入演算子という。

>>> width = 20.0
>>> height = 10.0
>>> area = width * height / 2
>>> print(area)
100.0

VBAの変数には宣言が必要。

=は代入演算子であり、等価演算子(Pythonでは==)でもある。

Dim width As Single: width = 20.0
Dim height As Single: height = 10.0
Dim area As Single: area = width * height / 2
MsgBox area '100が表示される

 

変数名のつけかた

Pythonでは

  • 半角英数と_(アンダーバー)でつけます。
  • ひらがなやカタカナや漢字もつかえますが、一般的にはつかいません。
  • 慣例として変数名は小文字でつけます。
  • 慣例として定数名は大文字でつけます。
  • 慣例として変数名は何をしめす値かがわかる名前をつけるようにします。
  • わかりやすい変数名にするために、複数の小文字の単語と単語を_(アンダーバー)でつなぐ命名法がよくつかわれています。

 

VBAでは

  • 文字 (英数字、漢字、ひらがな、カタカナ) と_(アンダーバー) でつけます。
  • 日本語の変数名もよくつかわれます。
  • 変数名の先頭の文字は、英字・漢字・ひらがな・カタカナのいずれかでなければなりません。
  • わかりやすい変数名にするために、単語と単語の区切りを大文字にする命名法がよくつかわれます。

 

つかえない変数名

Pythonでは

  • 変数名の1文字目には、数字・演算子・記号・予約語は使えません。

VBAでは

  • 変数名の1文字目には、数字・演算子・記号・予約語は使えません。

 

大文字と小文字

Pythonでは

  • 大文字と小文字は区別されます。point_apoint_Aは似た名前の別の変数です。

VBAでは

  • 大文字と小文字は区別されません。point_apoint_Aという変数は同じスコープの中では同時に宣言することはできません。

 

変数の型

Pythonでは

  • 変数の値には型がありますが、変数には型はありません。
  • 文字列が入っている変数に数値を代入してもエラーにはなりません。

 

VBAでは

  • 変数には型がありますが、どんな型の値でもいれられるバリアント型(Variant)の変数があります。
  • オブジェクトならなんでもいれられる総称オブジェクト型(Object)もあります。
  • 変数の型を宣言しない場合、すべての変数はバリアント型(Variant)になります。
  • 一般的にはOption Explicitを宣言して、変数の型宣言を強制する場合がおおいです。

 

定数

  • 値を保管する箱のようなもの
  • 箱の中身を変更することはできない
  • 定数をつかって式が書ける

 

Pythonの場合

Pythonには定数がありません。慣習的に大文字で書いた変数を他言語でいう定数として扱います。

TRIANGLE_WIDTH = 100

 

VBAの場合

VBAの定数はConstステートメントで宣言します。

Const TRIANGLE_WIDTH As Integer = 100

 

複合代入演算子

まず、VBAには複合代入演算子はありません。

Pythonでは

>>> age = 10
>>> age = age + 1
>>> age
20

を次のように書きかえることができます。

>>> age = 19
>>> age += 1
>>> age
20

age = age + 1age += 1とは同じ操作を意味します。

+=のことを複合代入演算子といいます。

 

複合代入演算子の種類

演算子 説明
+= a += b a = a + b。aにbをたした値を代入
-= a -= b a = a - b。aからbをひいた値を代入
*= a *= b a = a * b。aにbをかけた値を代入
/= a /= b a = a / b。aをbでわった値を代入
//= a //= b a = a // b。aをbでわった整数値を代入
%= a %= b a = a % b。aをbでわった余りを代入
**= a **= b a = a ** b。aをb回かけあわせた値を代入

 

+=を使って文字列を連結する

Pythonでは

>>> who = '猫'
>>> text = ''
>>> text += '我が輩は'
>>> text += who
>>> text += 'である。'
>>> text
'我が輩は猫である。'

VBAには複合代入演算子がないので

Dim who As String: who = "猫"
Dim text As String: text = "我が輩は"
text = text & who
text = text & "である。"
MsgBox text '我が輩は猫である。

 

変数に値を代入するとは

>>> walllet_1 = 100
>>> wallet_1
100

>>> wallet_2 = wallet_1
>>> walllet_2
100

>>> wallet_1
100

wallet_1の値をwallet_2に代入しても、wallet_1の値は100のままです。これはPythonでも、VBAでもおなじです。

これを「値渡し」といいます。「値」のコピーを渡すイメージですね。

これに対して「参照渡し」という引数の渡し方もあります。

この違いは「参照渡し メモリ番地」という語で検索するとたくさん説明がでてきますよ。

 

おわりに

「演算子」では意外とPythonとVBAに違いがでてきましたね。

Pythonはなんでもできるスクリプト言語、VBAはExcelというオブジェクトを操作するのに適した言語、という違いがでてきてだんだんと比較するのがむずかしくなってきたな、という印象です。

 

Copyright 2018 m-eye blog All Rights Reserved.