プロが教えるわが家の防犯対策術!

タイトルどおり、Callステートメントでいつでもイベント発生可能な準備ができるようにしたいと考えています。しかし、Sub 実行準備SUBでエラーが出ています。どこをどう直せばよいのか教えて頂きたいです。

Private Sub Auto_Open()
MsgBox "Ctrl + t でイベント実行準備を行います。"
Application.OnKey "^{t}", "実行準備SUB"
End Sub
'---------------------------------------------------
Sub 実行準備SUB()
Dim Target As Range
Target = Range(Cells(1, 1), Cells(100, 100))
Call Worksheet_Change(ByVal Target)
End Sub
'---------------------------------------------------
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim r As Range
For Each r In Target
If r.Column = 2 Then
r.Offset(0, -1).Value = Now
End If
Next r
End Sub

イベントは、シートの2列目のセルに変更があれば、1列目に日付時刻を記入するというものです。宜しくお願い致します。

A 回答 (4件)

素人の戯言ととでも思って読んでください。


>今後のためにも、VBAの構造的な理解、Callステートメント、プロシージャ等の理解を助けてくれる本などご存知でしたら是非教えて頂きたいです。
私も知りたいです。VBAの本に関心のあるものです。
しかしはっきり言ってお目にかかったことがありません。大村あつしさんの本を読んだ時に、所々それらしき臭いを嗅いだことを記憶しています。
あとは、9割9分初学者むけの似たり寄ったりの本ばかりです。
500題、1000題の多ページの本でも、知りたい課題を持って探すと、役に立たないことが多いです。
偶に雑誌や本の中の1文やWEBのVBA関連記事の中に、はっとする記述に出食わすことがあります。
これは自分の知識の発展・整理段階とも深く関連するようで、そういう段階に達した時に、始めて、はっとその記述の深い意味を悟るのです。始めは読んでもその意味に気がつきません。
またVBAもVBや他言語の仕組みなどを知ると、始めてVBAの
特徴や偏りなどが判るようです。回りのことを見ると自己が判る。
ですから詳しい本がそばにあれば万事解決でもないと思います。
本当に良く知っておられるプロは、小数だとは思いますが、世の中沢山いらっしゃると思いますが、忙しかったり、OKWEBにご縁がなくて、その知識を披露していただける機会がないようです。OKWEBでは、エクセルでもプロ向きの問題でない関数式の問題も多く、エクセル自身も、システムやプログラムのプロでも、必ずしもお詳しくはないのではと思います。コンピュタ界全体からすれば、エクセル関連知識も周辺部分的なことです。UNIX系統の方など、エクセルは詳しくないのではと想像します。たかが表計算ソフトのMSの1ソフトに過ぎぬと。
またOKWEBのエクセルの質問を全部目を通さないと、本件のような質問にぶつからないのですが、そのためには、毎日数時間メールに目を通す時間が要ります(私の経験から)。プロは多忙で、そんなことやってられないでしょう。
本件は理系の研究室の課題かと思いますが、良くあるニーズだと思いますので、もっと専門的に特化した世界の人や
資料に当たって見られることをお勧めします。
OKWEBは(コンピュタカテゴリについて)学術的・研究的・数学論理的・理系なことには無力ではないかと、3年間に
亘って、読み続けてきて感じます。
>Call
Callすることは、その時点で、実行するということです。
エクセルのChangeイベントなどを、VBE画面のメニュの実行
のSUB/ユーザーフォームの実行で実行しようとすると
実行できません。シート上のキーボードやマウス操作をイベントとしなければならないのは、何度も経験します。
イベントプロセジュアを通常のSUBプロセジュアの中に記述するのはおかしいと思います。
独立して記述するのが、出来るのが、メリットでもあると思います。
割り振りはシステムに任せる。
Changeイベントの前に行うべきことは、BOOKのOpenイベントなどで行うか、イベントを働かなくすれば良いのです。
EnablEevents=False なんていうのもあります。
>GPIBによるデータの取りこみの問題のようですが
時刻をデータに取り入れるなんて、良くある問題じゃないかと思います。VBAでなく、APIを使うとか、エクセルではなく、それ向けのソフトが沢山あると思います。通常はそれでの出力をCSV形式ファイルなどにして、後にエクセルに読みこませているのではと思います。
その辺を後学のためにも、研究されんことを。
たまたま身近なエクセルに飛びついた感あり、方向性の是正が必要では。
    • good
    • 0
この回答へのお礼

御回答大変勉強になりました。有難う御座います。#3の「お礼」で申し上げたとおり、身近にあるエクセルから今の方向性に至りました。API、何も全く分かりませんが、確かに耳にしたことがあります。大切なKyeword有難う御座います。取り合えず、今の知識内で最も解決手段に近いと思えるVBAでしばらく他のコード作成も行っていく方針です。しかし、並行して教わったことについても順次調べ、機会を見つけて挑戦していきたい次第です。これからもご迷惑をお掛けするかと思いますが、宜しくお願い致します。有難う御座いました。

お礼日時:2004/07/03 17:19

#2です。


>今後のためにも、VBAの構造的な理解、Callステートメント、
>プロシージャ等の理解を助けてくれる本などご存知でしたら
>是非教えて頂きたいです。
最近は、もっぱらヘルプを中心に参照していまして、今どきの本などについては存じ上げませんので、残念ながらご紹介できるようなネタを持ち合わせておりません。

ただ、現在お使いの本をもっとシャブリ尽くす、さらに関数の使用法やVBAの文法などは本の内容に加えてヘルプを確認するなどで理解はすすむのでは、と思います。

また、WebなどにあるExcelのサンプルなどで、結果がどのように得られるのかという過程を検証するというのも実力アップにつながるのではないかと思います。(OKWebの回答もいいサンプルになります。Excelに関しては「コンピューター [家庭向け] > ソフトウェア > Microsoftアプリケーション」のカテゴリで質問されるのが多いです。)


>ExFlgとはどういった意味なのでしょうか?
これは私が勝手に決めた変数です。(Public変数というものですが、これについてはヘルプや本で確認できると思います。)
http://okweb.jp/kotaeru.php3?q=911764
の質問で#1(=#2)さんが、フラグを使ってコントロールする方法がありますという紹介をされていますが、それの具体的な例に当たります。
フラグといのはプログラムをコントロールするための変数です。フラグ=旗のイメージで、旗が立っていたら、プログラム上のある処理を行う。旗が寝ていたら、何も行わないなどといった形で使います。
この場合でしたら、ワークブックが開いたときにフラグを寝かして置く。Ctrl+Tが押されたらフラグを立てる。ワークシートが変更された時に、フラグが立っていたら、時刻を記入するという流れになります。

(「フラグを立てる」とかは一般的にも使いますが、普通「寝かす」とは言わないです。説明のための表現ですので、お間違えなきよう)
    • good
    • 0
この回答へのお礼

御回答有難う御座います。ExFlgは、おっしゃられるとおり、Publicがあるので変数でした。焦ってしまいまして、意味不明なことばかり大変失礼致しました。

ヘルプと今使用の本で、目的を達成する努力が大切であることがよく分かりました。お忙しいところ御回答有難う御座いました。

私は某国立大学での修士生です。やはり、研究室にお金がなく未だにNEC製PC98を使っているほどです。そこからえるデータを扱うのに先輩方は、全て手作業で目的のデータを探したりそれを処理をされておりました。エクセルをよく使っていた私には、このRoutineWorkが無駄に思えて何とか簡単にできないか、というのがVBAに約半年前から携わるきっかけでした。やってみると、感動でした。しかし、だんだん本にも載っていないことが出てきて皆様に頼ることが多くなりました。正直、皆様同様、興味はあるのですが目的がVBAの習得ではないゆえ、これからもいくらかお聞きすることがあると思います。そのときは辛口で結構です。是非またよろしくお願い致します。有難う御座いました。

お礼日時:2004/07/03 17:08

失礼ですが、混迷を深めやすい形での質問の出し方になっています。



質問者さんは
http://okweb.jp/kotaeru.php3?q=911402
http://okweb.jp/kotaeru.php3?q=911764
という形で関連質問を順次出されていますね?それぞれ別の問題と言うことではなく、同じ問題を順次解決していくという方針だと思うのですが、以前の質問のリンクを示されていないので、別々の問題として考えると、特に今回のような質問であれば、意図不明なものになってしまっています。
他のプロシージャから Worksheet_Changeを呼び出す必要性も正当性も感じられません。(Private Subなので同一モジュールからならWorksheet_Changeは呼び出せますが、標準モジュールから呼び出すことは出来ません。)

Worksheet_Changeで指定した時刻表示をCtrl+Tを押したとき以降だけ有効にしたいということなら次のようにする方法が考えられます。

標準モジュールで
Public ExFlg As Boolean
'Subの定義の前
Sub 実行準備SUB()
ExFlg = True
End Sub

Workbookのイベントで
Private Sub Workbook_Open()
'Auto-Openでも可
MsgBox "Ctrl + t でイベント実行準備を行います。"
ExFlg = False
Application.OnKey "^{t}", "実行準備SUB"
End Sub

Worksheetのイベントで
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If ExFlg Then
  For Each r In Target
    If r.Column = 2 Then
      r.Offset(0, -1).Value = Now
    End If
  Next r
End If

End Sub

この回答への補足

御回答、御指摘有難う御座います。まったく、理解しないまま質問してしまいました。私はインプレス社[できる大辞典 Excel VBA]という厚めの本を参考にこれまで勉強してきました。恐らくまだこれから学ぶことが沢山あるかと思われます。しかし、今回質問させて頂いた一連のことについては、どうしてもこの本から深い理解を得ることができませんでした。また、インタネット上からも理解を得ようとしましたがそこまで至ることができませんでした。そのことで、皆様にご迷惑をお掛けいたしました。

 今後のためにも、VBAの構造的な理解、Callステートメント、プロシージャ等の理解を助けてくれる本などご存知でしたら是非教えて頂きたいです。

あと、またご迷惑をお掛けいたしますがExFlgとはどういった意味なのでしょうか?ヘルプ等調べましたが検索に該当致しませんでした。まだ、なぜワークシート、ブック、標準モジュールに分けて記述するかなど分からないことがありますがこれから理解に勤めていくつもりです。

 そして、この記述されたコードが私の意図する目的に完璧であったことに感謝、また自分に対して反省するところばかりです。有難う御座いました。

補足日時:2004/07/03 04:28
    • good
    • 0

実行準備って何でしょう?


Callしてるって事は実行準備では無く、実行したいって事?

正直、何をされたいのか良く解かりません。
シートの Change イベントは セルに入力されれば勝手に呼ばれます。

'-----------------------------------------------------------------
'「標準モジュール」に書く
Private Sub Auto_Open()
  MsgBox "Ctrl + t でイベント実行準備を行います。"
  Application.OnKey "^{t}", "実行準備SUB"
End Sub

'-----------------------------------------------------------------
'「標準モジュール」に書く
Sub 実行準備SUB()
Dim r As Range
  Set r = ActiveSheet.Range("B1:B100")
  r() = r()
End Sub

'-----------------------------------------------------------------
'「シートモジュール」に書く
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
 For Each r In Target
   If r.Column = 2 Then
    r.Offset(0, -1).Value = Now
   End If
 Next r
End Sub


これが希望の動作なら、シートモジュールの Change なんか不用で、下記にキーを割当てたのとなんら変わりが無い気がしますけど。。。

Sub aaaa()
  ActiveSheet.Range("A1:A100") = Now
End Sub

この回答への補足

 ご指摘有難う御座います。私は、ある値を自動計測してその値を例えば10秒毎にエクセルに取り込んでおります。しかし、測定値だけ取り込まれるためいつその値が取り込まれたかがわかりません。なので、自動計測による測定値をエクセルに取込中に、同時に測定された時刻も取り入れたいという目的で、このコードを作りました。

 ただ、測定前にエクセルに備考を記す必要があります。そのとき、入力するたびにイベントにより時刻が取り込まれることを避けたいのです。なので、実行準備SUBというプロシージャを作って制御しているつもりでした。

 しかし、ご指摘によってcallで呼び出されたイベントプロシージャは、呼び出された瞬間に実行されることが分かり、私の意図しない結果となることが始めて分かりました。有難う御座います。

 もし宜しければ、今回補足で申し上げたことをもとに質問を見ていただければ有難いです。また、今回ご指摘を受けたCallにより待機されるのではなく、すぐに実行される状態をどうにか待機させる方向にならないか、ご教授願います。長くなりましてご迷惑お掛けいたします。

補足日時:2004/07/03 03:19
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!