Accessから既存のExcelファイルを開き、そのファイル内にある
マクロを自動実行させたいと思っています。

Set obj = CreateObject("Excel.Application")
obj.Visible = True
Set Myobj = obj: Workbooks.Open ("エクセルファイル名(フルパス)")
Myobj.Run マクロ名

と書いているのですが、Excelファイルを開くところまでしか動いてくれません。
マクロ名の書き方が悪いのかもしれませんが、VBAに不慣れなため
どう直せばよいのかわかりません。
どうかよろしくお願いします。
ちなみに環境はWindows2000、Office2000です。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

私も良く知らないのですが、



エクセルのマクロに Publicを付けて宣言して、

>Myobj.Run マクロ名

obj.Run マクロ名
として実行してみてください。

この回答への補足

さっそく試してみましたが、残念ながらダメでした。
Excel側のマクロはもともとボタンがクリックされると実行するというものだったので
Privateになっていました。これをPublicにというのは、かなり的を得てると思ったのですが・・・。
マクロの格納場所も関係するのでしょうか?
もしご存知なら、また回答をお願いします。
まずは、回答ありがとうございました。

補足日時:2002/01/23 19:18
    • good
    • 0
この回答へのお礼

いろいろ試した結果、うまくいくようになりました。
やはり標準モジュールにマクロを置く必要があるようです。
ソースは obj.run ファイル名!Module1.マクロ名 としました。
もし調べて下さったいたら、お手数をおかけしてすいませんでした。
ヒントをいただき、ありがとうございました。

お礼日時:2002/01/23 20:22

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qexcelのマクロでrangeの選択がうまくいきません。

excelのマクロでrangeの選択がうまくいきません。
以下のマクロをsheet2に書きました。testcopyは動きますが、testcopy2は動きません。なぜなのでしょうか。どうすればいいのでしょうか。それ以外のマクロの部分との関係から、cellsを使い、数字を使ってrangeの処理をしたいのです。よろしくお願いします。

Sub testcopy()
Worksheets("sheet1").Range("B3:C10").Copy
Worksheets("sheet2").Range("e5").Select
ActiveSheet.Paste
End Sub

Sub testcopy2()
Worksheets("sheet1").Range(Cells(3, 2), Cells(10, 3)).Copy
Worksheets("sheet2").Range("e5").Select
ActiveSheet.Paste
End Sub

Aベストアンサー

>testcopyは動きますが、testcopy2は動きません

testcopyは「動作したり、しなかったりする」が正しい表現です。
  要するに今回testcopyが動いたのは▼たまたま▼ということです。

testcopy2 は当然ながらエラーになります。
何れにしろ、両方ともに問題があるということです。
その問題点は2つあります。

(1)アクティブでないシートのセルはSelect(Activate)できない
(2)複数のシートを扱うときのセルの参照は
   そのセルがどのシートのセルなのか明示する必要がある


これを踏まえて、、、、
---------------
●testcopy●

これが動作するのは
Sheet【2】がアクティブな状態で実行する場合です

Sheet【1】がアクティブな状態で実行すると
  Worksheets("sheet2").Range("e5").Select
ここで、問題点(1)の理由によりエラー。
で、先ずシートを選択、次にセルを選択と2段階にしないといけません。

  Worksheets("sheet2").Select
  ActiveSheet.Range("E5").Select

----------------
●testcopy2●

▼Sheet【1】がアクティブな状態で実行
  testcopyと同じ場所、同じ理由でエラー

▼Sheet【2】がアクティブな状態で実行
  Worksheets("sheet1").Range(Cells(3, 2), Cells(10, 3)).Copy
  ここで、問題点(2)により、エラー。
 
 Cellsの前にシートオブジェクトがないので
 Cells(3, 2), Cells(10, 3)はアクティブなSheet【2】のセルとみなされ
 (★実際はちょと違う場合もありますが今回はそう★)

 Worksheets("sheet1").Range(  ← Sheet【1】
 Cells(3, 2), Cells(10, 3))   ← Sheet【2】

このようにSheet【1】【2】が混在していることになり、エラー
で、Cellsの前にシートを付加してセルがどのシートのセルか明示してやる

Worksheets("sheet1").Range(Worksheets("sheet1").Cells(3, 2), Worksheets("sheet1").Cells(10, 3)).Copy
  
---------------------------------
で、質問者のコードを修正すると
'-------------
Sub testcopy()
 Worksheets("sheet1").Range("B3:C10").Copy
 With Worksheets("sheet2")
   .Select
   .Range("E5").Select
   .Paste
 End With
End Sub
'-------------

Sub testcopy2()
 With Worksheets("sheet1")
   .Range(.Cells(3, 2), .Cells(10, 3)).Copy
 End With
 With Worksheets("sheet2")
   .Select
   .Range("E5").Select
   .Paste
 End With
End Sub
'--------------

●ただ今回のような単純なコピーの場合は
 既出の回答にあるようにSelectなしで書くのがふうつです。
'-----------
Sub testcopy111()
 Worksheets("sheet1")
   .Range("B3:C10").Copy Worksheets("sheet2").Range("E5")
 End With
End Sub
'-----------
Sub testcopy222()
 Worksheets("sheet1")
  .Range(.Cells(3, 2), .Cells(10, 3)).Copy Worksheets("sheet2").Range("E5")
 End With
End Sub
'-----------

今回の件は重要事柄ですので覚えておきましょう。
以上です。
 

>testcopyは動きますが、testcopy2は動きません

testcopyは「動作したり、しなかったりする」が正しい表現です。
  要するに今回testcopyが動いたのは▼たまたま▼ということです。

testcopy2 は当然ながらエラーになります。
何れにしろ、両方ともに問題があるということです。
その問題点は2つあります。

(1)アクティブでないシートのセルはSelect(Activate)できない
(2)複数のシートを扱うときのセルの参照は
   そのセルがどのシートのセルなのか明示する必要がある


これを踏まえて、、、、
-...続きを読む

QExcel VBAについて質問します Set wb = Workbooks.Open(myFdr &

Excel VBAについて質問します

Set wb = Workbooks.Open(myFdr & "\" & fname) '開き,wbとする。
cnt = Worksheets.Count
For n = 1 To cnt
i = i + 1 'カウント
wb.Sheets(n).Range("A2").Copy mb.Sheets("Sheet1").Cells(i, "A") 'コピー
wb.Sheets(n).Range("D2").Copy mb.Sheets("Sheet1").Cells(i, "B") 'コピー
Next

この内容を値のコピーにするにはどうすれば良いでしょうか
よろしくお願いします。

Aベストアンサー

Open メソッドの前に、
Set mb = ThisWorkbooks
が必要です。

cnt = Worksheets.Count
実害はないけれども、
これは、cnt = wb.Worksheets.Count とします。

>値のコピーにするにはどうすれば良いでしょうか
コードを逆さまにすればよいです。

mb.Sheets("Sheet1").Cells(i, "A").Value = wb.Sheets(n).Range("A2").Value

QRange("K" & TR).Formula = で、セルにマクロで式を書きたいのですが

よろしくお願いします。いつもgooの皆さんには大変お世話になっています
エクセルは2013です

わけあって、セルにマクロで式を書いています
例えば TRは行を表す変数ですが
Range("K" & TR).Formula = "=IFERROR(AY" & TR & ","""")" と書いたマクロの結果は
=IFERROR(AY43,"") という式がRange("K" & TR) に書かれます

それでは、いま、マクロで下記のように書いているコード(TRは行を表す変数です)
Range("Z" & i) = Range("Z" & i - 1) - Range("AG" & TR) * 10000 は
Range("Z" & i).Formula = 
で書く場合、=の右側をどう書いたら良いでしょうか

色々とやってみたのですが狙った式になりません

この場合 変数 i を使っているので、もしかしたら、そもそも無理なことでしょうか

うまく説明できていませんがよろしくお願いします

Aベストアンサー

No.1です。申し訳ありません大ボケな回答をしていましました。

要するに↓ってことですよね? また勘違いしていたらスミマセン。

Range("Z" & i).Formula = "=Z" & i - 1 & "-AG" & TR & " * 10000"

QEXCEL 相対セル参照でいいものが、フルパスのブック名付きとなってしまう

シートAのあるエリアのセルを
シートBにて参照しています。
相対にてセル参照を作成したものですが、
日を置いて確認したところフルパスのブック名付きとなってしまったものです。

具体的には
当該のファイルが「会計報告.xls」で、c\temp に置かれている場合、
単純に「=Sheet1!A1」であってほしいのに、
「=c\temp\[会計報告.xls]Sheet1!A1」
といった具合にブックの名前まで記述されてしまう現象に悩まされているものです。

これでは他人に使用してもらうことができず困っています。

計算式の入ったセルを保護したのですがそれと何か関係があるのでしょうか?

Aベストアンサー

こんにちは。

前回のご質問(No.2968349)と質問内容がとても似ていますね。

>シートAのあるエリアのセルを
>シートBにて参照しています。

はっきりとした状況はつかめませんが、A,B が同じブックだとしたら、おそらく、作成中に、画面のウィンドウを分けずに、ブック自体を二重にしてしまったのではないかと思います。そして、別のものになってしまっているブックをたのを気がつかずに、参照設定してしまい、保存してしまっていた、と考えられます。

その場合は、

「=Sheet1!A1」
「=c\temp\[会計報告.xls]Sheet1!A1」

は、同じものだと思いますが、置換で、「=c\temp\[会計報告.xls]」を、単に「=」に置き換えてあげる必要があるかと思います。
計算式の保護は関係ありませんが、置換する場合は、一旦、計算式の保護は外さないとできません。

QVBA マクロ実行時エラー’1004RangeクラスのPasteSpecialメソッドが失敗

マクロ実行時に、エラー’1004RangeクラスのPasteSpecialメソッドが失敗と表記され、マクロが実行されません。

マクロの内容は、任意の範囲をコピー、新規book追加し、
新規bookに(1)Paste:=xlPasteValues (2)Paste:=xlPasteColumnWidths (3)Paste:=xlPasteFormats の順に貼り付けし保存するものです。

いろいろ調べては見たのですが、当方初心者の為、わからずじまいです。お手数ではございますが、どなたかご教授願います。
下記にマクロ内容全部記載します。
よろしくお願いします。

*********************************************************
*********************************************************
Sub 日報別ファイルに保存したい1()
Worksheets("日報").Range("A3:AF36").Copy
With Workbooks.Add
Cells.Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Cells.Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False

ApplicationDisplayAlerts = True '同名FILEが存在する場合'
ActiveWorkbook.SaveAs Filename:= _
"c:\日報\" & ActiveSheet.Range("J2") & "年" & ActiveSheet.Range("l2") & "月" & ActiveSheet.Range("n2") & "日_日報.xls" _
, FileFormat:=xlNormal
.Close file


End With

End Sub

マクロ実行時に、エラー’1004RangeクラスのPasteSpecialメソッドが失敗と表記され、マクロが実行されません。

マクロの内容は、任意の範囲をコピー、新規book追加し、
新規bookに(1)Paste:=xlPasteValues (2)Paste:=xlPasteColumnWidths (3)Paste:=xlPasteFormats の順に貼り付けし保存するものです。

いろいろ調べては見たのですが、当方初心者の為、わからずじまいです。お手数ではございますが、どなたかご教授願います。
下記にマクロ内容全部記載します。
よろしくお願いします。

***********...続きを読む

Aベストアンサー

こんにちは。

>結果、「ThisWorkbook」上の下記のマクロを削除すると、正常に動きだしました。
それは、Copy 範囲が、消えてしまうことで、PasteSpecial が利かなくなってしまうからです。

まず、シート名の長いコードは、これだけでよいはずです。

Private Sub Workbook_Activate()
 Select Case StrConv(Trim(ActiveSheet.Name), vbNarrow)
 Case "1" To "30", "日報"
  Application.Calculation = xlCalculationManual
 End Select
End Sub


-------------------------------------------
''もし、そのままでダメでしたら、 ' Application.EnableEvents = False 'イベントの介入を阻止する のところのコメント・ブロック('コードの手前のアポストロフィ)を外して、再度試してみてください。

Sub 日報別ファイルに保存したい2()
Dim myRng As Range
Set myRng = Worksheets("日報").Range("A3:AF36")
 ' Application.EnableEvents = False 'イベントの介入を阻止する

With Workbooks.Add
  myRng.Copy
 .ActiveSheet.Range("A1").PasteSpecial Paste:=xlPasteValues, _
             Operation:=xlNone, SkipBlanks:=False, Transpose:=False
  myRng.Copy
 .ActiveSheet.Range("A1").PasteSpecial Paste:=xlPasteColumnWidths, _
             Operation:=xlNone, SkipBlanks:=False, Transpose:=False
  myRng.Copy
 .ActiveSheet.Range("A1").PasteSpecial Paste:=xlPasteFormats, _
             Operation:=xlNone, SkipBlanks:=False, Transpose:=False
 
  Application.CutCopyMode = False
 
 ApplicationDisplayAlerts = True '**これは、そのままでは必要ないはずです。'
 
 ActiveWorkbook.SaveAs Filename:="c:\日報\" & ActiveSheet.Range("J2") & "年" & _
                 ActiveSheet.Range("l2") & "月" & _
                 ActiveSheet.Range("n2") & "日_日報.xls", _
                 FileFormat:=xlNormal
 .Close file
End With
Set myRng = Nothing
'Application.EnableEvents = True 'イベントマクロの活動を戻す

End Sub

こんにちは。

>結果、「ThisWorkbook」上の下記のマクロを削除すると、正常に動きだしました。
それは、Copy 範囲が、消えてしまうことで、PasteSpecial が利かなくなってしまうからです。

まず、シート名の長いコードは、これだけでよいはずです。

Private Sub Workbook_Activate()
 Select Case StrConv(Trim(ActiveSheet.Name), vbNarrow)
 Case "1" To "30", "日報"
  Application.Calculation = xlCalculationManual
 End Select
End Sub


-----------------------------------------...続きを読む

QExcel VBA  ”set xx=nothing” について

改めての質問です。
下記において、Set Wb = Nothing の位置は、考え方として、どこが正しいのでしょうか?

Sub myTitle()
Dim Wb As Workbook
Dim Ws As Worksheet
If xxxxx Then
Set Wb = Workbooks(myName)
Wb.Protect Structure:=False, Windows:=False
Application.DisplayAlerts = False
For Each Ws In Wb.Worksheets
If Left(Ws.Name, 1) = "H" Then Ws.Delete
Next
Application.DisplayAlerts = True
Wb.Protect Structure:=True, Windows:=False
Set Wb = Nothing
Set Ws = Nothing
End If

'Set Wb = Nothing やはり、この位置でしょうか?
'Set Ws = Nothing やはり、この位置でしょうか?

End Sub

上記は、オブジェクトWb,Wsに値を入れているIf文の中で開放をしています。
しかし、解放の位置は、If文の外(Dimに対応した位置)で、与えるのが、正しいのでしょうか?

Newを使った場合とか、現実に値を入れた時に生成される話と、こんがらかっているのです。
宜しく、お願い致します。

改めての質問です。
下記において、Set Wb = Nothing の位置は、考え方として、どこが正しいのでしょうか?

Sub myTitle()
Dim Wb As Workbook
Dim Ws As Worksheet
If xxxxx Then
Set Wb = Workbooks(myName)
Wb.Protect Structure:=False, Windows:=False
Application.DisplayAlerts = False
For Each Ws In Wb.Worksheets
If Left(Ws.Name, 1) = "H" Then Ws.Delete
Next
Application.DisplayAlerts = True
...続きを読む

Aベストアンサー

#1の回答者です。

実は、ご質問というのは、かなり議論になりやすい内容なのです。混乱すると思って、大幅に割愛しました。
>>人に披露するとか、ネットで口性(くちさが)がない人間がいるならともかく、あまり細かく気にすることはないような気がします。

これに尽きます。

学校などで教えるVBAでは、「オブジェクトは必ず開放しなさい」といわれますが、本当は、一種の建前とか作法のようなものなのだろうと思います。作法だったらとやかくいう筋合いでもないけれども、多少、気にかけなくてはならないのは、いい加減にすると、トラブルを起こすものがあるということです。それは、外部参照で常駐してしまうもので、代表は、"InternetExplorer.Application" です。

基本的には、
Sub ~ End Sub の中で、オブジェクトを確保したものは、その中で終わります。つまり、End Sub とすれば、開放されてしまいます。例外はあります。モジュール変数やグローバル変数は、例外になります。

>Wsなんかは、Forループを抜けた段階で nothing になっています。
>(なぜだか、理解していませんが)。つまり、
>Set Ws=nothing
>の記述は不要ということ。

これは、For Each Ws In Wb.Worksheets ~ Next のNext で、Wsが、終わっているということです。
他にもWith Workbooks(myName) ~ End With で、End With で終わっています。

余計わからなくなるかもしれませんが、こちらを読んでみてください。

「Set a = Nothing」のお話
http://www.moug.net/tech/exvba/0150027.html

その中に、
「「Set a = Nothing」をして、早め早めにオブジェクトへの参照を解除することで効率化につながります。」

このような文章がありますが、見栄えを優先していたから、最初のご質問で、If xxxxx Then がなにをするかにもよりますが、10年前ぐらいは、その外に、Set Wb = Workbooks(myName)としたのが常識でしたが、それが変わりつつあると思います。

かえって、わかりにくくなったかもしれません。

P.S.
もし、余裕があるのでしたら、こちらも考えてみてください。
http://oshiete.goo.ne.jp/qa/9064013.html
ご質問者は、解決しないとしています。私も理由はわかりません。


今までの話の延長上にあるはずなのです。今度は、付帯するオブジェクトとは別に、マクロ自身にも64Kというメモリ枠があります。残念ながら、こちらは、ローカル・ウィンドウでは、見れません。そのマクロ自身のメモリ枠を越えたり、End やEnd Sub、エラー信号 などで、そのメモリを壊してしまえば、たぶん、マクロは中途で止まってしまうはずです。マクロが走る本線が終われば、それを載せているオブジェクトも運ばなくなって、開放してしまうと思うのです。

#1の回答者です。

実は、ご質問というのは、かなり議論になりやすい内容なのです。混乱すると思って、大幅に割愛しました。
>>人に披露するとか、ネットで口性(くちさが)がない人間がいるならともかく、あまり細かく気にすることはないような気がします。

これに尽きます。

学校などで教えるVBAでは、「オブジェクトは必ず開放しなさい」といわれますが、本当は、一種の建前とか作法のようなものなのだろうと思います。作法だったらとやかくいう筋合いでもないけれども、多少、気にかけなくてはならないのは、...続きを読む

QExcelマクロでRange("A1:A5,C1:C5")をCellsで書きたいのですが

マクロ初心者です。
Excelマクロでグラフを作成するときに、元データを指定する所で、
Source:=Range("A1:A5,C1:C5")とするような場合、
「A1」とかアルファベットでの番地指定ではなく、
Cellsを用いて書きたいのです。

Source:=Range("A1:A5")であれば、
Source:=Range(Cells(1, 1), Cells(5, 1))と書けばいいことは分かるのですが、範囲指定を複数にする場合が分からないのです。

よろしくお願いします。

Aベストアンサー

Unionを使用したらできると思います。

Source:=Union(Range(Cells(1, 1), Cells(5, 1)), Range(Cells(1, 3), Cells(5, 3)))

今Excelがインストールされてないパソコンで作業していないので確認はしていないのですが・・・。

よかったら参考にして下さい

QWorkBooksをオープンさせずにシートにコピーしたい【EXCEL VBA】

よろしくお願いします。
今あるブックにあるシートを別のブックにコピーしたいのですが、今考えているのは

ここから////////
'ブックを開く
Workbooks.Open コピー元のブックのパス
'シートをコピー
Worksheets.Item(コピーするシート名).Copy _
after:=Workbooks(コピー先のブック名).Sheets(1)

'ブックを閉じる
Application.DisplayAlerts = False
Workbooks.Item(コピー元のブック名)Close True
Application.DisplayAlerts = True
ここまで////

なのですが、コピーものとのブックが複数ある時、画面がチラチラしてしまいます。ブックをオープンさせずにシートを他ブックにコピーさせる方法ってないでしょうか。
ご存知の方がいらっしゃいましたら、ご教授お願いします。

Aベストアンサー

画面のチラツキを押さえたいだけなら、画面の更新をやめればいいだけじゃないでしょうか?

ブックを開く前に
Application.ScreenUpdating = False
ブック閉じてから
Application.ScreenUpdating = True

Qエクセルのマクロ(range)について

マクロの作りと理解の方法について教えてください。

今、日報を作り直しています。
以前作成した方は、このように作っていました。


Worksheets("日報").Select
Range("Q7:Q23").Value = Range("U7:U23").Value
Range("S7:S59").Value = Range("V7:V59").Value
Range("A1").Select
MsgBox " 転写を終了しました。"
End Sub


マクロでは複数の行列を指定していますが、1行だけ表すと、
具体的な表とデータの変化の仕方とするとこのようになっています。

M    O    Q     S       U     V
個数 金額  累計個数 金額金額 (=M+Q) (=O+S)
0、   0、   100、   1000、    100、   1000 
1,初期状態

10、  100、  100、   1000、    110、   1100
2,個数を入力すると、計算式を入力してあるUとVの数が変わる

10、  100、   110、   1100、    120、   1200
3,マクロを実行すると、UとVの数がQとSに入力され、計算式を入力してあるUとVの数がさらに変わる。

0、   0、    110、   1100、   110、    1100
4,MとOの数をゼロ(クリア)にすると、計算式を入力してあるUとVの数が変わる。     


なかなか理解できないのは、Range("Q7:Q23").Value = Range("U7:U23").Valueの部分で、
2,の後にマクロを実行すると、U 110、V 1100がQ 100とS 1000に書き込まれることです。
通常の計算式だと=は対象となったセルをそのまま表示していると思うのですがのですが、
マクロに書いてある式だと3,のところでUとVの数をQとSに書き込んであります。
なぜ=なのにマクロでは一方のセルに数を書き込んでいるのでしょうか。
また、QやSをUやVへ書き込んでいないのでしょうか。

どなたか詳しく教えていただけると幸いです。

マクロの作りと理解の方法について教えてください。

今、日報を作り直しています。
以前作成した方は、このように作っていました。


Worksheets("日報").Select
Range("Q7:Q23").Value = Range("U7:U23").Value
Range("S7:S59").Value = Range("V7:V59").Value
Range("A1").Select
MsgBox " 転写を終了しました。"
End Sub


マクロでは複数の行列を指定していますが、1行だけ表すと、
具体的な表とデータの変化の仕方とするとこのようになっています。

M    O    Q     S...続きを読む

Aベストアンサー

プログラミング言語では、一般的に、
「=」は、右辺から左辺への「代入」
を意味します。

マクロ = Visual Basic = プログラミング言語
なので、Excelにおける「=」とは少し意味合いが違っています。

QExcel Workbook_SheetSelectionChange マクロについて

特定のセルの値をユーザーによって変えられないようにするために、
Workbook_SheetSelectionChangeを使ったのですが、
Workbook_SheetSelectionChangeでは、そのセルを選択した時にトリガが掛かり、
実際問題としてそのセルの値を変えられてしまった後の対応はしてくれません。
そこで、[Enter]が押されて、隣りのセルに移動(選択)されたことを掴んで、対処しています。
もっとスマートな方法はないでしょうか?
下のマクロでは、[Enter]を押さずに、マウスで他のセルをクリックして
抜けてしまうと、結果、値を変えられてしまいます。
・・・そのセルの値が変更されたことをキャッチして、eventマクロ
のトリガが掛かると、理想的かと、考えますが・・・
宜しくお願い致します。

Public DataORG As String
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
Application.MoveAfterReturnDirection = xlToRight
If Target.Address = "$A$1" Then
DataORG = Target.Value
MsgBox "このセルの値を変更することはできません"
ElseIf Target.Address = "$B$1" Then
Application.EnableEvents = False
Range("$A$1").Value = DataORG
Application.EnableEvents = True
End If
End Sub

PS. 勿論、このままでは、セルA1には、未来永劫、値を入れることはできません。
  他のルーチンにて「Application.EnableEvents = False」を設定して
  入力を可能としております。
  シートの保護も考えましたが、別の理由により、止めました。

特定のセルの値をユーザーによって変えられないようにするために、
Workbook_SheetSelectionChangeを使ったのですが、
Workbook_SheetSelectionChangeでは、そのセルを選択した時にトリガが掛かり、
実際問題としてそのセルの値を変えられてしまった後の対応はしてくれません。
そこで、[Enter]が押されて、隣りのセルに移動(選択)されたことを掴んで、対処しています。
もっとスマートな方法はないでしょうか?
下のマクロでは、[Enter]を押さずに、マウスで他のセルをクリックして
抜けてしまうと、結果...続きを読む

Aベストアンサー

こんにちは。

atom_28さんのコンセプトからすれば、私の書いたものは、意図しているものとは違うかもしれません。そのときは、また別なものを考えましょう。

>PS. 勿論、このままでは、セルA1には、未来永劫、値を入れることはできません。
>  他のルーチンにて「Application.EnableEvents = False」を設定して
>  入力を可能としております。

数式入力の状態は、マクロは待機状態になります。この時に、変更が出来てしまいます。

以下の話は、もう少し筋道建てれば分かりやすくなるのですが、とりあえず、②のカスタムプロパティ側から読んでみてください。

① SheetChangeの場合
>intersectの意味することから考えると、[Enter]が入力された後に起動されているような気がするし。
その通り、[Enter]で起動しています。

SheetSelectionChangeは、本来、移動した時にイベントが発生しています。これも、誤解しやすいのです。

Not Intersect(Target, Range("A1")) Is Nothing
この意味は、二重否定ですから、すぐに分からりづらいです。なぜ利用したかというと、ピンポイントで削除は他の方法でも防げることでも、そこを含めた広い面を、消去(delete)などされると、プロテクト(保護)を掛けてない限りは、一般的には防ぐことはできません。

これは、行の削除でも対応します。

話が前後していますが、②のカスタムプロパティを利用したマクロを考えてみました。一例です。

'標準モジュール
Sub Auto_Open() 'ファイルを開いた時に設定
Dim Dummy As Variant
  On Error Resume Next
 With ThisWorkbook 'カスタムプロパティに入っているかチェック
  Dummy = .CustomDocumentProperties("DataORG").Value
 If Err() = 0 Then '入っていれば次へ
  GoTo EndLine
 End If
 End With
  With ThisWorkbook.CustomDocumentProperties
    .Add Name:="DataORG", _
      LinkToContent:=False, _
      Type:=msoPropertyTypeString, _
      Value:="SettingName" '設定された文字
  End With
EndLine:
  Call ThisWorkbook.SetData '標準モジュールから、Private 変数は設定できません。
  On Error GoTo 0
End Sub

'ThisWorkbook モジュール
'Private DataORG As String '前回の続きなら、すでに変数はあるはず。
Sub SetData() 'Private 変数に設定
 DataORG = ThisWorkbook.CustomDocumentProperties("DataORG").Value
End Sub


②「カスタムプロパティ」とは、「プロパティ」の詳細プロパティの中のユーザー設定

https://support.office.com/ja-jp/article/Office-%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e3%83%97%e3%83%ad%e3%83%91%e3%83%86%e3%82%a3%e3%82%92%e8%a1%a8%e7%a4%ba%e3%81%be%e3%81%9f%e3%81%af%e5%a4%89%e6%9b%b4%e3%81%99%e3%82%8b-21d604c2-481e-4379-8e54-1dd4622c6b75?ui=ja-JP&rs=ja-JP&ad=JP

プロパティに製作者や会社名を入れますが、自分の作った項目も登録できるようになっています。今回の全体の流れからすると、コンセプトが違いすぎるかもしれません。レジストリを使おうかと思う時に、こんな便利なものがあるということを思い出していただければよいかと思います。

サンプルマクロを紹介します。なお、他にも、隠しデータを入れる場所はいろいろあります。VeryHiddenのシートの中にデータを置いて使っている人もみかけます。
「静的(static)に保管」というのは、当たり前ですが、保管しても定数として消えていないことです。セルですと、消してしまうことがありますが、プロバティは知っていて行わなければ消えません。

サンプルマクロ
'//
Sub TestForCustomDProperties()
'初めての登録
  On Error Resume Next
  With ThisWorkbook.CustomDocumentProperties '--アクティブブックに対して
    .Add Name:="テーマ", _
      LinkToContent:=False, _
      Type:=msoPropertyTypeString, _
      Value:="イベント型マクロ"      '--文字列型のプロパティ
    .Add Name:="ログ番号", _
      LinkToContent:=False, _
      Type:=msoPropertyTypeNumber, _
      Value:=9050730            '--数値型のプロパティ
    .Add Name:="登録日", _
      LinkToContent:=False, _
      Type:=msoPropertyTypeDate, _
      Value:="2015/08/23"          '--日付型のプロパティ
  End With
  If Err() <> 0 Then MsgBox Err.Description
  On Error GoTo 0
End Sub
Sub OutputProperties()
Dim myTheme As String
Dim LogNum As Long
Dim tDate As Date
'出力
 With ThisWorkbook
  myTheme = .CustomDocumentProperties("テーマ")
  LogNum = .CustomDocumentProperties("ログ番号")
  tDate = .CustomDocumentProperties("登録日")
 End With
 MsgBox myTheme & vbCrLf & LogNum & " : " & tDate
End Sub
Sub ChangePropertyies()
Dim myTheme As String
'修正用
 With ThisWorkbook
  .CustomDocumentProperties("テーマ").Value = "SheetChange とSelectionSheetChangeについて。"
 End With
 Call OutputProperties
End Sub

こんにちは。

atom_28さんのコンセプトからすれば、私の書いたものは、意図しているものとは違うかもしれません。そのときは、また別なものを考えましょう。

>PS. 勿論、このままでは、セルA1には、未来永劫、値を入れることはできません。
>  他のルーチンにて「Application.EnableEvents = False」を設定して
>  入力を可能としております。

数式入力の状態は、マクロは待機状態になります。この時に、変更が出来てしまいます。

以下の話は、もう少し筋道建てれば分かりやすくなるのですが、とりあえず...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報