No Programming, No Life

プログラミング関連の話題や雑記

VBAのマクロで外部コマンドを呼び出すサンプル

はじめに

諸事情があり、Excelのマクロから外部コマンドを呼び出す必要がありました。その際書いたスクリプトのメモです。

動作環境

Win10 × Excel2016でしか動作確認しています。

サンプルコード

Dim wsh As Object
Dim exec As Object
Dim command As String
Dim result As String

Set wsh = CreateObject("WScript.Shell")
command = "〜〜〜"
Set exec = wsh.exec("%ComSpec% /c " & command)

Dim line As String
' ★★★ポイント1★★★
Do While exec.Status = 0
    If Not exec.StdOut.AtEndOfStream Then
        line = exec.StdOut.ReadLine ' 標準出力の1行読み込み
        ' 〜〜〜(処理)〜〜〜
        Do Events
    End If
Loop

' ★★★ポイント2★★★
Do Until exec.StdOut.AtEndOfStream
    line = exec.StdOut.ReadLine ' 標準出力の1行読み込み
    ' 〜〜〜(処理)〜〜〜
    Do Events
Loop

Set exec = Nothing
Set wsh = Nothing

ポイント1

exec.Status0 になるまで待ち合わせを行っています。wsh#exec した後はコマンド実行が終わるまで時間がかかるかもしれないためです。ちなみにこの位置で標準出力のストリームを読み込んで置かないと、データ量が多いとふんずまるみたいです。

ポイント2

ここは、残りの標準出力のストリームを最後まで読み込んでいる部分です。

同じ処理を2箇所で書かていてカッコ悪いので、実用的なコードを書くときはちゃんと関数化などしましょう。

おわり。

参考サイト

https://m.srad.jp/~IR.0-4/journal/572274

Rubyのチュートリアルっぽい記事の一覧

Rubyチュートリアルっぽい記事の一覧はこちら

Ruby1 - プログラミング言語Rubyの概要 - No Programming, No Life

Ruby2 - Rubyの基礎文法 - No Programming, No Life

Ruby3 - Rubyの基礎文法 - 条件分岐 - No Programming, No Life

Ruby4 - Rubyの真偽値 - No Programming, No Life

Ruby4 - Rubyの真偽値

Rubyで「真」を表すのは何ですか?

以外のすべての値です。ちなみに true です。

じゃあ、Rubyで「偽」を表すのは何ですか?

falsenil です。 Rubyではこの2つ以外はすべて なので、0 (整数のゼロ) や、'' (空文字) も となります。気をつけて下さい。

関連記事

Rubyのチュートリアルっぽい記事の一覧 - No Programming, No Life

Rubyが令和に対応したみたいです

Ruby v2.6.3でdateライブラリが令和に対応したみたいです。

$ irb
irb(main):001:0> require 'date'
=> true
irb(main):002:0> Date.new(2019, 5, 1).jisx0301
=> "R01.05.01"
irb(main):003:0> Date.new(2019, 4, 30).jisx0301
=> "H31.04.30"
irb(main):004:0> exit
$

おしまい。

参考

Ruby 2.6.3 リリース

Python1 - PythonでHello World

当記事はPythonの文法 | Think Twiceにマージしました。


Q1.この記事は何ですか?

Pythonのハローワールドです。動作確認はv3.7.3にて行っています。

Q2. PythonでのHelloWorldのコード例を教えて下さい

hello1.py

print("Hello, World")
print("Hello, ")
print("World")

print関数で文字列を出力。

出力結果

$ python hello1.py 
Hello, World
Hello, 
World

Q3. あれ?2つめのHelloWorldは改行されてしまっていますね?

はい、普通に呼び出すと、改行コード付きで出力されます。 改行コードなしにするには、end="" を付けます。

hello2.py

print("Hello, ", end="") # end="" とすると改行しないみたい
print("World")

出力結果

$ python hello2.py 
Hello, World

Q4. # はもしかして行コメントですか?

はい、#以降が行コメントになります。

# これはコメント
print('Hello') # これもコメント

ちなみに、複数行コメントもあります。複数行コメントは以下のようにクォーテーションを3つで囲んだ形になります。

'''
この行はコメント
この行はコメント
'''

あとで詳しく出てきますが、Pythonはインデントでブロックを表現する言語なので、複数行コメントの場合は、インデントに注意して下さい。(同じブロックにいないとエラーになります)

hello3.py

for x in {1, 2, 3}:
  print("text")
  '''
  forのブロック内でのコメントは
  同じインデントを付けて書く必要がある
  '''
  print(x)

'''
この行もコメント(forのブロックの外)
この行もコメント(forのブロックの外)
'''

出力結果

$ python hello3.py 
text
1
text
2
text
3

参考

python3で改行なしprintをする。 - てきとーなブログ

Pythonでのコメントアウトの書き方 | UX MILK

Pythonのmac(Mojave 10.14.5)へのインストール

私はmacを使っているので、こちらを参考にHomebrew + pyenvでv3系で最新の3.7.3をインストールしてみました。 ちなみに途中、うまくインストールが進行しなかったので、ここ を参考に解決しました。

前提

環境:macOS Mojave バージョン 10.14.5

Homebrewは最新版。

pyenvのインストール

$ brew pyenv install 

~/.bash_profile に以下を追記

export PYENV_ROOT=${HOME}/.pyenv
if [ -d "${PYENV_ROOT}" ]; then
    export PATH=${PYENV_ROOT}/bin:$PATH
    eval "$(pyenv init -)"
fi

pyenvでインストール可能な一覧を確認

$ pyenv install -l
Available versions:
  2.1.3
  2.2.3
  2.3.7
  (中略)
  3.7.0
  3.7-dev
  3.7.1
  3.7.2
  3.7.3
  3.8-dev
  (中略)
  stackless-3.4.2
  stackless-3.4.7
  stackless-3.5.4

pyenvで使用するバージョンのインストール

$ pyenv install 3.7.3

pyenvでインストールされたバージョンの確認

pyenvでインストールされたPythonは、~/.pyenv以下にインストールされる。 インストールされているバージョンを確認。

$ pyenv versions
* system
  3.7.3 (set by /Users/(ユーザ名)/.pyenv/version)

使用するバージョンを確定

$ pyenv global 3.7.3
$ pyenv versions
  system
* 3.7.3 (set by /Users/(ユーザ名)/.pyenv/version)
$ python --version
Python 3.7.3

これでOK。

参考

Python3インストール(Mac編) - Qiita

MacOS mojaveでpyenvを使ってpythonがインストールできない時 - Qiita

Ruby3 - Rubyの基礎文法 - 条件分岐

概要

ここでは、Rubyの条件分岐の文法について見ていきます。 Rubyでの条件分岐には if else elsifunless 使います。caseも使えます。少し変わりどころだと、後置if, 後置unlessもあります。

if文

まずは if ですが、以下のように記述し、条件 の場合に 処理 が実行されます。 条件 でない場合は処理は実行されません。

if 条件 then
  処理
end

ちなみに、thenは省略可能で、以下のようにも書けます。

if 条件
  処理
end

こちらの方がスッキリしていますね。

実行例)

ifels1.rb

a = 10
if a > 5 then
  puts 'aは5より大きい'
end
$ ruby ifels1.rb 
aは5より大きい

else文

if条件に合致する場合でしたが、else条件に合致しなかった場合に処理をさせたい場合に使います。

if 条件 then
  処理1
else
  処理2
end

この場合だと、 条件に合致しなければ、処理2の部分が実行されます。

実行例)

ifels2.rb

a = 3
if a > 5 then
  puts 'aは5より大きい'
else
  puts 'aは5より大きくない'
end
$ ruby ifels2.rb
aは5より大きくない

elsif文

ifの条件は満たさなかった時に、その次に判定する条件を書きたい場合にはelsifを使います。

ifels3.rb

a = 40
if a > 50 then
  puts 'aは50より大きい'
elsif a > 20 then
  puts 'aは50より大きくはないが、20よりは大きい'
else
  puts 'aは20以下'
end
$ ruby ifels3.rb
aは50より大きくはないが、20よりは大きい

unless文

ifの逆の構文になります。〜じゃなかったら処理を実行するといった感じです。 unless1.rb

a = 10
unless a > 10 then
  puts 'aは10より大きくない'
end
$ ruby unless1.rb
aは10より大きくない

ちなみにunlessにはelseは付けられますが、elsifは付けられません。

後置if, 後置unless

式の末尾にif 条件 や unless 条件 を置いて、条件 が真、または偽なら前部分の式を実行するというクールなやつです。利用はお好みで。

if_unless_modifier1.rb

a = 10
puts 'aは10以上です' if a >= 10

この場合だと puts 〜 の部分が実行されるかどうかは aの値による感じです。

$ ruby if_unless_modifier1.rb 
aは10以上です

if_unless_modifier2.rb

a = 10
puts 'aは10より大きくない' unless a > 10
$ ruby if_unless_modifier2.rb 
aは10より大きくない

case文

caseは複数の条件分岐を一気にこなしたい場合に利用します。caseの後に比較したい を置いて、whenの後に置いたとマッチする場合、その処理が実行されます。whenは複数配置でき、すべてのwhenにマッチしなかった場合はelseに書いた処理が実行されます。

casewhen1 then
  処理1
when2 then
  処理2
else
  処理その他
end

ちなみに、お察しの通りthenは省略できます。 また、whenの後の値はカンマで区切ると複数指定できます。

casewhen1, 値2 then
  処理1
when3, 値4 then
  処理2
else
処理その他
end

使用例)

case1.rb

age = 14
case age
when 0, 1, 2
  puts "赤ちゃん"
when 3 .. 6
  puts "幼児"
when 7 .. 12
  puts "小学生"
when 13 .. 18
  puts "中高生"
else
  puts "大人!"
end
$ ruby case1.rb 
中高生

参考

Ruby if...else, case, unless

ruby unless文にelsifはないよ。。。 - Qiita

関連記事

Rubyのチュートリアルっぽい記事の一覧 - No Programming, No Life