布団が俺を呼んでいる

丘山大一のぶろぐ

VBAのプロシージャ呼び出しの括弧のまとめ

VBAでプロシージャ呼び出しの際、引数に括弧をつけるのかつけないのか・つけたらどうなるのかが異様に分かりづらかったので真面目に調べました。
というか自分の整理のためにまとめました。
参考にさせて頂いたのは下記ブログです。
先人の知恵はありがたや~


VBAプロシージャの引数の基本

  • 基本は参照渡し
  • 戻り値を使わないプロシージャ呼び出しは括弧不要
  • 戻り値を使うプロシージャ呼び出しは括弧が必要
  • Call を使う時は括弧が必要
  • Call を使った時は参照渡し
  • 個別に括弧をつけると値渡し


実際の呼び出し


下記のhogeとhoge2という二つのFunction プロシージャの呼び出しパターンとその時の引数の渡し方で試します。
実際にコピペして動作させた方が分かりやい(と思います)。

Option Explicit

' 呼び出すFunction

Function hoge(x As Integer) As Integer
  x = x * 2
  hoge = x + 1
End Function

Function hoge2(x As Integer, y As Integer) As Integer
  x = x * 2
  y = y * 2
  hoge2 = x + y
End Function

' 以下、呼び出し側

Sub fuga()
  Dim a As Integer
  Dim b As Integer
    
  ' 戻り値を使用しない・括弧をつけないで呼び出す。引数は参照渡し。
  a = 3
  hoge a
  MsgBox a ' message 6
  
  ' 戻り値を使用しない・括弧をつけて呼び出す。個別に括弧をつけているので引数は値渡し。
  a = 3
  hoge (a)
  MsgBox a ' message 3
   
  ' Callで呼び出す・引数は参照渡し。
  a = 3
  Call hoge(a)
  MsgBox a ' message 6
  
  ' Callで呼び出す・個別に括弧をつけているので引数は渡し。
  a = 3
  Call hoge((a))
  MsgBox a ' message 3
    
  ' 戻り値を使用する。引数は参照渡し。
  a = 3
  b = hoge(a)
  MsgBox a ' message 6
  MsgBox b ' message 7
  
  ' 戻り値を使用する。個別に括弧をつけているので引数は渡し。
  a = 3
  b = hoge((a))
  MsgBox a ' message 3
  MsgBox b ' message 7
        
  ' Callで呼び出す・引数内部で計算してしまっているので……これは値渡し?
  a = 3
  b = 2
  Call hoge(a + b)
  MsgBox a ' message 3
  MsgBox b ' message 2
  
  ' 戻り値を使用しない・括弧をつけないで呼び出す。引数は参照渡し。
  a = 3
  b = 2
  hoge2 a, b
  MsgBox a ' message 6
  MsgBox b ' message 4
  
  
  ' 戻り値を使用しない・第一引数は括弧をつけているので値渡し。・第二引数は括弧をつけていないので参照渡し。
  a = 3
  b = 2
  hoge2 (a), b
  MsgBox a ' message 3
  MsgBox b ' message 4
    
  ' Callで呼び出す・引数は参照渡し。
  a = 3
  b = 2
  Call hoge2(a, b)
  MsgBox a ' message 6
  MsgBox b ' message 4
  
  a = 3
  b = 2
  ' Callで呼び出す・第一引数は括弧をつけているので値渡し。・第二引数は括弧をつけていないので参照渡し。
  MsgBox a ' message 3
  MsgBox b ' message 4
  
  ' hoge2(a, b) ' 戻り値を使わないのに括弧をつけているので構文はエラー
  ' Call hoge2 a, b  ' Callで呼んでいるのに括弧がないので構文エラー
  
End Sub


ハマりそうなところ


個別に括弧をつけた場合、値渡しになるわけですが、これプロシージャの定義がByRef でも上書きされるんですよね。
これは参考元の方に書かれていますが、単に先に評価しているからなのでしょうね。

という理屈は分かった気になりましたが、やっぱり分かりづらいです。


2020/2/19 :間違いがあったので修正

コメントを書く

布団が俺を呼んでいる | 管理者ユーザなのにexeファイルのファイル操作できなくなる現象

布団が俺を呼んでいる

丘山大一のぶろぐ

管理者ユーザなのにexeファイルのファイル操作できなくなる現象

exeファイルのプロパティのセキュリティにアクセスできなくなる現象とも。
実害が出るレベルではまりました。


現象

ファイルを削除しようとすると、
「このファイルを削除するには管理者の権限が必要です」→「続行」→
「この操作を実行するアクセス許可が必要です」→「再試行」→
以降ループするので「キャンセル」せざるをえなくなる

リネームしようとすると、
「このファイルの名前を変更するには管理者の権限が必要です」→「続行」→
「この操作を実行するアクセス許可が必要です」→「再試行」→
以降ループするので「キャンセル」せざるをえなくなる

実行しようとすると、
「指定されたデバイス、パス、またはファイルにアクセスできません。これらの項目にアクセスするための適切なアクセス許可がない可能性があります」
で、メッセージ内容から「セキュリティが変なのか……」と考えファイルのプロパティからセキュリティを
開くと、たしかに権限がふられていない。ファイルの所有者の所有者も見えない。
しかし、権限をふろうとしても権限をふれない。

どういうこっちゃねん。


原因

他のユーザがexeファイルをロードしている状態で、さらに別ユーザがexeファイルを削除していたため。


原因詳細

エクセルファイルなんかで「別のプログラムがファイルを開いているので操作を完了できません」を見ることがあった人も
多いと思いますが、その複雑版です。共有フォルダに配置した、複数のユーザがたたくexeファイルで起きました。
登場人物は下記。

  • Aユーザ:exeファイルを実行していた人
  • Bユーザ:exeファイルを先に削除した人
  • Cユーザ:管理者であり、exeファイルを削除したい人

Aユーザは、Cユーザのマシン内の共有フォルダに入ったexeファイルを実行しています。起動後なので、exeはロードが終わった状態です。
続いて Bユーザは、そのexeファイルを削除します。Aがexe実行中でもファイル削除できます(Bのエクスプローラからは消える)
最後にCユーザが共有フォルダに入ったexeファイルを削除を実施しますが上記��現象」にはまり何もできなくなります。
Cマシン内の共有フォルダにあるexeは、Bによって削除された亡霊みたいな状態。


対応

exeにアクセスしている人を強制的に全部切断すれば解消されます。
というか先に切断しておきましょう。


泣き言

これWindowsのバグでは、という気がしなくもない。けど何かしら事情があってこうなっている気もする。

コメントを書く