[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2006/04/07(Fri) 13:16
投稿者名:ダンボ
URL :
タイトル:
コンパイルエラーになるのですが
EXCEL2000のVBAです。

cmdLOCKという名前のコマンドボタンを持ったアクティブシートに対して
ForceLockという関数を2通りの方法でコーディング/コールしてみました。
方式1は問題無いのですが、方式2ではForceLockの中で、
「コンパイルエラー メソッドまたはデータメンバが見つかりません。」
が起きます。cmdLOCKが理解できないということらしいです。
どうしてエラーになるのでしょうか?ActiveSheet以外でもこの関数は
使いたいので方式2でコーディングしたいのですが。

(方式1)
Call ForceLock()とコールする
Public Function ForceLock()
With ActiveSheet
    .Protect UserInterfaceOnly:=True
    .cmdLOCK.Caption = "シート保護をはずす"
End With
End Function

(方式2)
Call ForceLock(ActiveSheet)とコールする
Public Function ForceLock(ST As Worksheet)
With ST
    .Protect UserInterfaceOnly:=True
    .cmdLOCK.Caption = "シート保護をはずす"
End With
End Function

投稿時間:2006/04/07(Fri) 14:58
投稿者名:Blue
Eメール:
URL :
タイトル:
Re: コンパイルエラーになるのですが
ActiveSheetの時は、自分が Sheet1オブジェクト なのか Sheet2オブジェクト なのか
わかっているのでうまくいっているようですね。

Object型で渡してみてはどうでしょうか?
Public Function ForceLock(ST As Object)

投稿時間:2006/04/07(Fri) 16:52
投稿者名:ダンボ
URL :
タイトル:
[まあ解決]コンパイルエラーになるのですが
Blueさん、いつもお世話になっています。ありがとうございました。

> Public Function ForceLock(ST As Object)
で、問題なく動作しました。理屈は。。理解できません。


自己流解説(解釈)

・関数中にWith ActiveSheetが明示されている場合、CallされたときにSheet内のオブジェクト
を全部調べてコードとの整合性をチェックして、矛盾があればコンパイルエラーにする。
今回はActiveSheetの中にcmdLockボタンがあったからエラーは無し。

・ForceLock(ST As Worksheet)の場合、一般的なWorksheetオブジェクトで用意されている
オブジェクト全部を調べてコードとの整合性をチェックする。ボタンコントロールなどは
一般的なWorksheetオブジェクトで用意していないからコンパイルエラーにする。

・ForceLock(ST As Object)の場合、Objectが何だかわからないから事前チェックはしない(できない)。
だからコンパイルエラーはなくて、あるとすれば実行時エラーだけ。

投稿時間:2006/04/11(Tue) 23:45
投稿者名:いな
Eメール:
URL :
タイトル:
なんだか解らないならば
誤爆のようですので削除

投稿時間:2006/04/12(Wed) 00:50
投稿者名:ダンボ
URL :
タイトル:
Re: なんだか解らないならば
いなさん、どうもです。

自己流解説(解釈)の部分はVB言語システムの処理について推測を書きました。
わかりづらくてすみません。

VBは多分、文法等の事前チェック(コンパイル)を行った後実行に移す。
可能な限り事前チェックを厚くしようとして、コード内にActiveSheetと
明記されていれば、そこに含まれている(コントロール)オブジェクトも
チェック材料に含める。
ところがST As WorkSheetと引数でActiveSheetを渡そうとした場合は、
仮引数と実引数のバインドは多分文法チェック(コンパイル)の後の段階で
行うのでコンパイル時点ではそこに含まれている(コントロール)オブジェクト
が不明なままチェックを行う。従って見つからない。ST As Objectの
場合は使用者責任としてコンパイルは手薄く行う。

だからこれを回避するためにST As WorkSheetの場合でもcmdLockを明示的に
宣言すれば良いのではとも考えて試してみました。
Public Function ForceLock(ST As WorkSheet)
Dim cmdLock as MsForms.CommandButton

結果は、、、やっぱりコンパイルエラーになりましたわ。

投稿時間:2006/04/12(Wed) 03:27
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: コンパイルエラーになるのですが
> 方式2でコーディングしたいのですが。

 CallByName(ST, "cmdLock", VbGet).Caption = "シート保護をはずす"

のようにしてみるとか。

投稿時間:2006/04/12(Wed) 06:54
投稿者名:ダンボ
URL :
タイトル:
Re^2: コンパイルエラーになるのですが
魔界の仮面弁士 さん、いつもお世話になっています。
下記コーディングでコンパイルエラーも起きず実行結果も正しく、
仮引数のもやもやも晴れました。どうもありがとうございます。

実行部分が2行だとST As Objectでも大差ないですが、長いコードだとチェックの
ためにも仮引数タイプはあわせられるものならあわせたほうが良いですよね。
ただ、本件の解決方法の場合cmdLOCKの操作が1回だったから良いけど
複数回操作する場合はちょっとコードが見づらくなりますね。

Public Function ForceLock(ST As Worksheet)
With ST
     .Protect UserInterfaceOnly:=True
     CallByName(ST, "cmdLOCK", VbGet).Caption = "シート保護をはずす"
End With
End Function

投稿時間:2006/04/12(Wed) 16:34
投稿者名:y4yama
URL :
タイトル:
Re^3: コンパイルエラーになるのですが
たいしたことじゃないんですが、疑問に思ったので教えてください。
「cmdLOCKという名前のコマンドボタン」は、複数のシートにあるんですね?
そして、あるシートがアクティブの時にcmdLOCKが押されるんでしょうか?
(だったら、ActiveSheet.cmdLOCK...で充分のような・・・)
変なことを聞きましてスミマセン。よろしくお願いします

投稿時間:2006/04/12(Wed) 17:11
投稿者名:ダンボ
URL :
タイトル:
Re^4: コンパイルエラーになるのですが
> 「cmdLOCKという名前のコマンドボタン」は、複数のシートにあるんですね?
はい、そうですね。

> そして、あるシートがアクティブの時にcmdLOCKが押されるんでしょうか?
そうとは限らないのが、本件の質問の発端で。。(いや本件は押すんじゃないです)


基本仕様/外部仕様:
・各シートには保護したいセルと記入可能なセルがある。
・原則としてガチガチにプロテクトしたいのだがそうも行かない事情がある。
 (Excel2000ではシート保護時には非保護セルでも書式の変更ができない)
・従って各シートにcmdLOCKボタンを設けて一時的にシート保護を解除可能にする。
 (cmdLOCKボタンはトグルでキャプションが「シート保護を掛ける」/「シート保護をはずす」)
・ユーザが最後に終了するときにシート保護を解除したまま終わる可能性は高い。
・従ってExcelブック起動時にすべてのシートのプロテクトを強制的に掛ける。
 (cmdLOCKボタンのキャプションも「シート保護をはずす」に初期設定する)

この最後の処理のためにForceLock()を使います。ユーザがまだシートを操作できない内にですね。
各シートを順次ActivateしていってForceLockを(方式1)で呼ぶという手もありますけれど、
・意味のないActivateは嫌だ。美しくない。
・各シートのActivatedイベントには別な処理がある/追加可能性がある。特殊な呼び出し場合を排除して
おきたい。

投稿時間:2006/04/13(Thu) 07:35
投稿者名:y4yama
URL :
タイトル:
Re^5: コンパイルエラーになるのですが
ダンボさん、よくわかりました。使い方と密接な関係があるんですね
ホント変な質問だったでしょうね
ありがとうございました!