空白を含むファイルパスを変数として扱う方法
年の瀬に年末エントリーを書こうと思っていたのに…。 それは明日にでもかこう。
exeファイルを実行したい。
どうも。久しぶりのVBAに関する記事です。
VBAで実行ファイルを実行したい際にはWshShellオブジェクト
のRunメソッド
を使いますよね。
この時、実行したいファイルのパスを与えなければなりません。
しかし、ファイルパスに空白が含まれていると正しく実行できず、二重引用符で囲む必要があります。
例えば
C:\Program Files\FOGE.exe
を実行したいときは以下のように書きます。
Dim ShellObject As Object Set ShellObject = CreateObject("WScript.Shell") ShellObject.Run """C:\Program Files\FOGE.exe"""
このファイルパスをプログラム上に直接書き込まずに変数として取得して使用したい場合は少し工夫が必要です。
取得したいファイルパスがA1セルに入力されているとします。 するとファイルパスは以下のように取得しますね。
Dim filePath as String filePath = Cells(1, 1) 'あるいはRange("A1")でもいいけど
そして取得したファイルパスに引用符を文字列として付けたいのですが、普通にダブルコーテーションで囲って文字列を結合しようとしても意味がありません。
Dim filePath as String filePath = """ & Cells(1, 1) & """ Debug.Print filePath ' " & Cells(1, 1) & " ' 上のように出力されてしまう。
このような場合は文字コードを直接指定してあげるとよさそうです。
Dim filePath as String filePath = Chr(34) & Cells(1, 1) & Chr(34) Debug.Print filePath ' "C:\Program Files\FOGE.exe" ' これでおっけー
複数の引数を渡して実行する方法
おまけ
実行ファイルFOGE.exeに加えて引数Arg1, Arg2を与えたいとします。 これらのファイルも空白含んでいるとして、次のようにするといいでしょう。
filePath = Chr(34) & Cells(1, 1) & Chr(34) Arg1 = Chr(34) & Cells(2, 1) & Chr(34) Arg2 = Chr(34) & Cells(3, 1) & Chr(34) Dim ShellObject As Object Set ShellObject = CreateObject("WScript.Shell") ShellObject.Run filePath & " " & Arg1 & " " & Arg2
以上です。
MendeleyへのExportでブロックされる時の対処法
論文をScience DirectからMendeleyに直接ダウンロードする
Science DirectにはMendeleyに直接論文をダウンロードできる機能があります。 この辺の連携がしっかりしていないと、一度Science Directで論文をダウンロードしてからMendeleyのソフトを立ち上げてインポートする必要があります。
この面倒な作業が、Science Direct - Menedely間ではボタン一つで連携が取れるのです。 しかし、実際に使ってみるとアンチウイルスソフトにブロックされてしまいました。 Macでは有名なセキュリティソフトに「avast!」があると思いますが、こちらを利用しているとMendeleyにエクスポートする際にブロックされてしまします。
今回はその対処法を描いてみます。
対処方法
Shellメモ
メモ用の走り書きだし正確性や可読性については勘弁してほしい。
$@, $*, "$@", "$*"の違い
引数に与えられる位置パラメータについて。
shell, bashなどではコマンドラインから実行する際に、引数は位置パラメータに設定される。
これを使って引数をプログラムに与えることが出来るののだ。また引数として(-oとか-hの様な)オプションを与えることも出来るようになる。
もっともオプションを使えるようにするためにはコマンドラインの入力を解析するためにプログラムは複雑になる。
こんな時はオプション解析コマンド getopts
を使えばかなり楽になるが、ここでは関係ないためこの辺にとどめておく。
閑話休題。
この位置パラメータについて、具体的にかくとこんな感じだ。
コマンド | 説明 |
---|---|
$0 | コマンドラインで実行されたファイルのファイルパスかコマンド |
$1~$n | コマンドラインで入力された引数を先頭から順番に格納してる |
$# | コマンドラインで入力された引数の総数を表す。 |
$@ | コマンドラインで入力された引数の全てが格納される |
$* | $@と同じだが" " で囲んだ時の挙動が"$@"と違う |
こんな感じだ、と言われてもピンとこないと思うので試してみる。
ここで実行するshellのファイルはtest.sh
とする。
また実行するtest.sh
はカレントディレクトリに配置されているものとする。
まずは与えられた引数がどのように格納されているかみる。
$0と$1 ~ $nについて
#!/bin/sh echo $0 echo $1 echo $2 echo $3 echo $4
上記のtest.sh
を次のように実行すればこのように出力される。
$ sh test.sh aa bb cc test.sh aa bb cc
ここでsh
はshellを実行する宣言みたいなもの。
test.sh
は実行するファイル
aa bb cc
が引数となる。
正しくはtest.sh
も引数である。多分
この時、コマンドラインに与えられた引数は3つのみなのに、echo $4
としているため、出力の最後は空白行となっている。
このようにコードに書いた$n
と引数が一致しなくてもプログラムはエラーを吐かないので注意が必要。
$10以上の時
また、$n
の整数 nは基本的にはなんぼでもいけるが、$10
以降は$1
と0
と分けて認識されてしまうため問題が生じる。
試しにやってみる。
#!/bin/sh echo $10 echo ${10}
$ sh test.sh aa bb cc dd ee ff gg hh ii jj aa0 jj
このように$10
だと第一引数のaa
と、$10
の認識されなかった0
が出力されてしまう。
この対策として${n}
として{ }
で囲うことで正しく出力されていることがわかる。
$@と$*について
この2つの挙動は同じである。
試しにやってみる。
#!/bin/sh echo "\$@ -> $@" echo "\$* -> $*"
これはこの様な結果になる。
$ sh test.sh aa bb cc dd ee ff gg hh ii jj $@ -> aa bb cc dd ee ff gg hh ii jj $* -> aa bb cc dd ee ff gg hh ii jj
同じですね。 もっと言えば、引数全てがスペース区切りで繋げられた状態で返されると認識しているといいかもしれない。
"$@"と"$*"について
試しにやってみる。
#!/bin/sh echo "\$@ -> "$@"" echo "\$* -> "$@""
これはこの様な結果になる。
$ sh test.sh aa bb cc dd ee ff gg hh ii jj $@ -> aa bb cc dd ee ff gg hh ii jj $* -> aa bb cc dd ee ff gg hh ii jj
$@
や$*
の時と同じ様に見える。
ここで$#
とset
を使って引数の挙動を観察してみる。
#!/bin/sh set -- "$@" echo "$@" echo $# set -- "$*" echo "$*" echo $#
$ sh test.sh aa bb cc dd ee ff gg hh ii jj aa bb cc dd ee ff gg hh ii jj 10 aa bb cc dd ee ff gg hh ii jj 1
$@
の場合、set
を通っても引数の数は10のまま変わない。
これに対して$*
の場合は全て一つの引数としてまとめられたことがわかる。
したがって、この二つは引数全体を一つのパラメータとして扱う場合と引数を個別のパラメータとして扱う場合に使い分けることが出来る。
単に引数をLogとして出力する場合なんかは"$*"
を使えば良い。
また、補足になるが引数を" "
で囲んだ場合は囲まれた中身が1つのパラメータとして認識される。
#!/bin/sh echo $# echo $@
$ sh test.sh aa bb "cc dd" 3 aa bb cc dd
$@と"$@"の違い
この2つの違いは引数を" "
で囲んだ部分がある場合に" "
内を1つの引数として認識するかどうかである。
試しにやってみる。
echo $# set -- $@ echo "$@" echo $# set -- "$@" echo "$@" echo $#
$ sh test.sh aa bb "cc dd" 3 aa bb cc dd 4 aa bb cc dd 4
実行時は" "
で囲まれた部分が1つの引数として認識されている。
しかし、$@
でset
しなおすと" "
が無視されて引数が3から4に増えたことがわかる。
したがってset
する場合やfor
で値を取り出す場合に注意が必要である。
試しにfor
で引数を取り出してみる。
echo \$@ for i in $@; do echo ${i} done echo "" echo "\$@" for i in "$@"; do echo ${i} done echo "" echo "\$*" for i in "$*"; do echo ${i} done
$sh test.sh aa bb "cc dd" $@ aa bb cc dd "$@" aa bb cc dd "$*" aa bb cc dd ExchangeCharCo
この様に、$@
の場合は" "
を無視されていることがわかる。
また、"$*"
では引数が1つにまとめられている事もわかる。
位置パラメータの再設定
プログラム内で位置パラメータを再設定することはできない。 例えば以下の様に再設定しようとしてもエラーが吐かれて終わる。
#!/bin/sh $1=jj
位置パラメータを変更したい場合にはset
を用いる。
#!/bin/sh echo $1 $2 set kk ll echo $1 $2
$ sh test.sh aa bb aa bb kk ll
バラ星雲とコーン星雲
Photoshopを導入後初の天体写真
先日、僕もついにPhotoshopを導入する運びとなりました。
運びとなりました。と仰々しく書いていますが、ただ年間1万円近くの利用料金を払ってPhotoshopをインストールしただけですけどね。
それにしても、買い切り型よりもサブスクリプション型の方がなんとなく購入するまで構えてしまいがちです。
さて、Photoshopを導入したのはいいものの、ここ最近観測に行けていません。
不憫に思ったのか、Photoshop練習用にと師匠が撮影データを送ってきてくれました。
対称星はバラ星雲とコーン星雲です。また、見難いですがカタツムリ星雲も写っています。
色々と書きたいこともありますが、あまり時間がないので今日は成果報告として画像を上げるだけにします。
なんの面白みもない記事ですみません。
Photoshopでの画像処理法についてはまたいつかあげようと思います。
Mixhostのサーバー障害で記事が消えた時の対処法
事の発端
先日からレンタルサーバーのMixhostにてサーバー障害が発生していたようです。
Investigating: 現在データベースサーバー障害が発生しており、接続が不安定な状況となっております。
— mixhost Status (@mixhoststatus) 2018年12月8日
新たな情報が入り次第、すぐに状況をご報告いたします。
ご利用中のお客様にはご迷惑をおかけしますことを深くお詫び申し上げます。 https://t.co/ARWWMUvpMQ
Mixhostのサーバーは復旧したようですが、サーバーのデータが1週間前に巻き戻しされブログなどの記事も消されてしまったようです。
これによって今朝からTwitterではプチ騒動になっている模様。
Mixhostのサーバー障害で12月1日~9日までの記事が全部消えた話 https://t.co/463yHrHyoL #Mixhost #サーバー障害
— 鈴林 (@unatia_rinrin) 2018年12月9日
僕自身、このサーバーを使っていないのであまり詳しくは把握していませんが、これの対処法について書きたいと思います。
問題と対処法
問題
Mixhostデータベースのデータが1週間程度前の状態に戻された。
その結果、12月1日から12月9日までのブログ記事等は消滅。対処法
サーバーから記事が消えてしまっても、Googleによってクロールされていればキャッシュが作成されているはず。 このキャッシュデータにアクセスして削除された記事を復旧する。 support.google.com
以上となります。
具体的な方法
※ 僕はMixhostを使っていないので画像などははてなブログになっています。
まず自分のWebサイトをGoogleで検索します。
写真矢印の部分をクリックすると
キャッシュ
と表示されるのでそこをクリック。すると削除以前のブログページを開くことができますので、削除された記事のタイトルをコピーしておきます。
コピーしたブログタイトルをGoogleで再び検索します。
2番と同様に検索結果からキャッシュページを表示します。
これで削除されたページが見れるようになるはずです。
記事が削除されても、キャッシュから復旧できればあとはコピペするなりして元に戻せるのではないかと思います。
Plotlyをオンラインで使う方法 | Plotly徹底解説
オンラインプロット
PlotlyではFreeアカウントを取得することでオンライン上で作成したグラフの編集、保存が可能になります。
オンラインプロットでは自分のアカウント上にグラフを保存するため、アカウント登録が必要です。
そしてグラフをプロットするにはAPIキーというのを取得する必要があります。非常に簡単に出来るので心配ありません。
Freeアカウントでは公開状態でグラフが保存されますが、年会費を支払うことでプライベート保存が可能になります。
詳細は次の料金プランについての説明を見てください。
APIキーの取得
オンライン上にプロットする為にはAPIキーを取得する必要があります。
APIキーはAPI Keyページから設定できるはずです。
正しくリンクが飛ばない場合は、自分のアカウントからSettings > API Keys
とクリックしてください。
初めてAPIを設定する方は API Key
の下にある部分のRegenerate Key
をクリックして保存します。
生成されたAPIキーは念のため人に見られない安全な場所に保存しておいてください。
一度登録してしまえばあとはあまり使うことはありません。
APIキーの登録
APIキーはPythonを使ってコマンドラインから設定できます。
あるいはAPIキー登録ようのpythonファイルを作成して実行してもいいかもしれません。
$ python >>> import plotly >>> plotly.tools.set_credentials_file(username='DemoAccount', api_key='lr1c37zw81')
usernameのDemoAccount
とapi_keyのlr1c37zw81
を自分のものと置き換えます。
また、.credentials
ファイルの設定からも行なえます。
- Finedrを開き > 移動 > フォルダへ移動(⬆︎⌘G)とメニューバーから選択。
~/.plotly/
と入力.credentials
ファイルを開き、usernameとapi_keyの部分に記入- 保存して閉じる。
pythonでAPIキーを登録した場合は、こちらのファイルが書き換えられているはずです。
APIキーに問題がありそうな場合はこちらのファイルを見直すか、新たにAPIキーを発行して登録し直すといいかもしれません。
オンラインプロットの公開範囲
プロットするデータが第三者などに閲覧されては困る場合、公開範囲に気を使わなければなりません。
Plotlyでは3つの公開範囲が用意されています。
種類 | 説明 |
---|---|
Public | 誰でもグラフを閲覧することが可能です。あなたのアカウントプロフィール上に、そして検索エンジンの結果にも表示されます。そしてPlotlyにログインすることなく閲覧が可能です。 |
Private | あなただけがグラフを閲覧できます。この設定によってPlotlyのフィード上、あなたのアカウントプロフィール上、そして検索エンジンの検索結果に表示されなくなります。 このグラフを閲覧するにはあなたがPlotlyアカウントにログインする必要があります。また、他のPlotlyユーザーに対して個人的に公開も可能ですが、相手もログインする必要があります。 |
Secret | 与えられたシークレットリンクを持つ人は誰でもグラフを見れます。WebページやIPython notebookに埋め込んだ場合も誰でも見ることができます。また閲覧にログインは不要です。しかしながらPrivateと同様に検索結果などには表示されません。 |
公開範囲を設定する場合はPython上で以下のように実行します。
import plotly plotly.tools.set_config_file(world_readable=False, sharing='private') #↓はデフォルトの設定 plotly.tools.set_config_file(world_readable=True, sharing='public')
また、公開範囲はプロット時に指定することもできます。
plot()
のなかでsharing='private'
と入力するだけです。
import plotly.plotly as py import plotly.graph_objs as go pass # プロットのための処理 # 系列データの設定 data = [trace0, trace1] #グラフのプロット # sharingで公開範囲の設定をする。 py.plot(data, filename = 'basic-line' \ , auto_open=True, sharing='private')
オンラインプロットで描画
グラフのオンラインプロットにはplotly.plotly
の中のメソッドを用います。
公式ドキュメントではimport plotly.plotly as py
として利用しています。
そしてオンラインプロットにはpy.plot
とpy.iplot
の2つのメソッドが用意されています。
違いは以下のようになります。
py.plot
: 任意のURLを返し、オプションで指定することでブラウザ上にグラフを表示します。py.iplot
: エディタ上に直接プロットすることができます。
どちらで実行してもPlotlyアカウント上に保存されます。
ということで、とりあえず考えなしに以下のコードを実行して見てください。
import plotly.plotly as py import plotly.graph_objs as go # 各系列のデータを設定 trace0 = go.Scatter( x=[1, 2, 3, 4], y=[10, 15, 13, 17] ) trace1 = go.Scatter( x=[1, 2, 3, 4], y=[16, 5, 11, 9] ) data = [trace0, trace1] py.plot(data, filename = 'basic-line', auto_open=True)
自分のアカウントが開き、以下のようなグラフが表示されるかと思います。
因みに、py.plot
メソッドではプロット時の設定をオプションで与えることができます。
上ではfilename
で保存するファイル名、auto_open
でグラフの表示・非表示の設定を行なっています。
auto_open
ではTrue
の時は自動的にブラウザを起動しグラフを表示しますが、False
だとグラフを保存したURLを返してくれます。
,またAPIキーの設定などが済んでいないとエラーが生じるので注意してください。 エラーは以下のような内容で出るかと思います。
#APIキーが指定されていない時 Make sure that you're logged in as ユーザー名. Need help? Please try searching Plotly's <a href='http://stackoverflow.com/questions/tagged/plotly'>Stack Over flow channel</a>. #APIキーとユーザー名が指定されていない時 Aw, snap! We didn't get a username with your request. Don't have an account? https://plot.ly/api_signup Questions? accounts@plot.ly
といった感じ今回は簡単な使い方説明に留めておきました。
Plotlyではかなり凝ったレイアウトにすることができるのでそちらも紹介していきます。
レイアウトの参考にはデモ記事を参照してください。
tanisukestr.hatenablog.com
Plotlyをオフラインで使う方法 | Plotly徹底解説
ここではオフラインで描画する方法について説明します。
オフラインモードでは以下の2つのやり方でグラフを描画できます。
- ファイルを実行し、ブラウザ上に表示
- エディタであるAtomやjupyterの画面上に表示
またオフラインでプロットする場合、Plotlyのアカウント取得やAPIキーの設定はする必要はありません。
しかし、のちにオンライン上でグラブ編集したり保存するためにはアカウントが必要になるので登録(無料)することをお勧めします。
ではやって行きます。
普通にプロットする
オフラインで描画するために以下の2つをインポートします。
# import plotly.plotly as py <- オンライン用 import plotly.offline as offline # <- オフライン用 import plotly.graph_objs as go
プロットする場合は
offline.plot(data, filename = 'basic-line', auto_open=True)
となります。以下のプログラムをコピペして実行してみてください。
# 以下の2つをインポート import plotly.offline as offline import plotly.graph_objs as go trace0 = go.Scatter( x=[1, 2, 3, 4], y=[10, 15, 13, 17] ) trace1 = go.Scatter( x=[1, 2, 3, 4], y=[16, 5, 11, 10] ) data = [trace0, trace1] # オフラインでプロット offline.plot(data, filename = 'basic-line', auto_open=True)
ここで、offline.plot
の引数にあるauto_open
をTrue
とすると、作成したグラフを自動的にブラウザで表示してくれます。
auto_open=False
とするとグラフは表示されず生成したファイルのパスを返します。
何れにしてもHTMLファイルが生成され、再度表示することが可能になります。
デフォルトの設定はTrue
となっています。
Atom, jupyter notebookで描画する
基本的には前節で説明したやり方と変わりありませんが、4点ほど違いがあります。
- import文の後ろに
offline.init_notebook_mode()
を追加 offline.plot()
ではなくoffline.iplot()
を使う- HTMLファイルは出力されない。
auto_open
は使えない。(エディタ上で直接見るので当然ですね。)
その他は基本的に同じはずです。
offline.init_notebook_mode()について*1
これはデフォルトでoffline.init_notebook_mode(connected=False)
となり、ブラウザに必要なライブラリ(plotly.js)を読み込みます。
常にオフラインで実行する場合はoffline.init_notebook_mode()
とします。
しかし、この方法だとファイルにplotly.jsを直接読み込むことになるのでファイルサイズが数メガバイト増加します。
試しに以下のコードを使ってjupyter notebookのファイルサイズの変化をみてみます。
# 以下の2つをインポート import plotly.offline as offline import plotly.graph_objs as go offline.init_notebook_mode(connected=False) trace0 = go.Scatter( x=[1, 2, 3, 4], y=[10, 15, 13, 17] ) trace1 = go.Scatter( x=[1, 2, 3, 4], y=[16, 5, 11, 10] ) data = [trace0, trace1] # オフラインでプロット offline.iplot(data, filename = 'basic-line')
このコードでconnected=False
とconnected=True
を切り替えると
- Trueの時 : 5 KB
- Falseの時 : 5.9 MB
と、ファイルサイズが増加することがわかります。
一時的にでもインターネットに接続できる場合や、ファイルサイズを小さくしたい場合にはTrue
を選べば良いと思います。