[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『パブリックでのワークシートのSet』(ろでっち)
パブリックで変数を設定すると、モジュール内で共用の変数で使えるのは知っています。
なので、これと同じことを、ワークシートでもやりたいと思っています。
Public ws1 as Worksheets
set ws1 = WorkSheets("A")
これができませんでした。
これをするにはどのようにすればよろしいでしょうか?
ご教授のほどをよろしくお願いいたします。
< 使用 Excel:Excel2010、使用 OS:Windows7 >
Public ws1 as Worksheets だとワークシートの集まりにならないか?
Public ws1 as Worksheet ではどうか。
(ねむねむ) 2017/07/18(火) 22:32
例文・・・というかほぼそのままです。
Public ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet, ws4 As Worksheet
Set ws1 = Worksheet("A") Set ws2 = Worksheet("B") Set ws3 = Worksheet("C") Set ws4 = Worksheet("D")
Option Explicit
Sub Size()
If ws1.Range("A1") = "小" Then Call Mini() ElseIf ws1.Range("A1") = "中" Then Call Midle() ElseIf ws1.Range("A1") = "大" Then Call Big() Else MsgBox "サイズ欄に「大」「中」「小」のいずれかを入力してください", vbCritical Exit Sub End If
End Sub
Sub Mini()
Msgbox WS2.name & "です" End sub
Sub Middle()
Msgbox WS3.name & "です" End sub
Sub Big()
Msgbox WS4.name & "です" End sub
すいません、よろしくお願いします。
(ろでっち) 2017/07/19(水) 10:07
それを実行しようとすると Set ws1 = Worksheet("A") の部分で プロシージャの外では無効です。 と出ないか? メッセージどおりの意味だが。 (ねむねむ) 2017/07/19(水) 10:11
ステートメントはプロシージャ内でしか使えない。 ThisWorkbookモジュールのWorkbook_Open()イベントにでも >Set ws1 = Worksheet("A") >Set ws2 = Worksheet("B") >Set ws3 = Worksheet("C") >Set ws4 = Worksheet("D") を移動させてくれ。 あと、羹に懲りてなますを吹くになっているが Worksheet(〜) は Worksheets(〜) で。
(ねむねむ) 2017/07/19(水) 10:18
ねむねむさん >ThisWorkbookモジュールのWorkbook_Open()イベントにでも とのことですが、こけた時に変数の値消えてしまうので、都度Setしたほうが、私は、よいと思います。
ろでっちさん 例文であれば、変数を使わず、引数として渡すというのはどうですか? Sub test() With Sheets("A") Select Case .Range("A1").Value Case "大" Call Size(Sheets("B")) Case "中" Call Size(Sheets("C")) Case "小" Call Size(Sheets("D")) Case Else MsgBox "サイズ欄に「大」「中」「小」のいずれかを入力してください", vbCritical End Select End With End Sub Sub Size(ByVal ws As Worksheet) MsgBox ws.Name & "です" End Sub
(稲葉) 2017/07/19(水) 10:53
貴重な意見ありがとうございます。
稲葉様kら頂きましたコードで動きました。
ただ、なんでうまく動いているのかを理解しておきたくて・・・。
すいませんが教えていただけないでしょか。
Call Size(Sheets("B"))
この部分で、ワークシートオブジェクト自体を渡している?のでしょうか?
よろしくお願い申し上げます。
(ろでっち) 2017/07/19(水) 11:15
技術的なことについて詳しく説明できる自信はありません。
http://vbae.odyssey-com.co.jp/column/no29_1.html
http://excel-ubara.com/excelvba4/EXCEL218.html
http://www.239-programing.com/excel-vba/basic/basic017_5.html
引数の渡し方については上記サイトを参照していただくとわかりやすいと思います。
今回ByValで宣言してしまいましたが、変数ではなくオブジェクトそのものを渡してるのでByRefでも 結果は変わらないと思います。 が、今後活用される場合に注意が必要と思ってByValで宣言してあります。 ByValで受け取った場合と、ByRefで受け取った場合の違いを実感してみてください。
Sub test2() Dim ws1 As Worksheet Set ws1 = Sheets("A") MsgBox ws1.Name Call test3(ws1) MsgBox ws1.Name Call test4(ws1) MsgBox ws1.Name End Sub Sub test3(ByVal ws As Worksheet) Set ws = Sheets("B") End Sub Sub test4(ByRef ws As Worksheet) Set ws = Sheets("B") End Sub
(稲葉) 2017/07/19(水) 12:08
Sub Size() Dim iw As Long Dim cw As String
iw = InStr("大中小", Sheets("A").Range("A1")) If 0 < iw Then cw = Array("B", "C", "D")(iw - 1) MsgBox Sheets(cw).Name & "です" Else MsgBox "サイズ欄に「大」「中」「小」のいずれかを入力してください", vbCritical End If End Sub (???) 2017/07/19(水) 17:25
正直ByREF使うと頭がぐちゃぐちゃになりそうですね(^^;
???様
コードの方ありがとうございます。
こちらの方も試してみます!。
とりあえず、こちらでアドバイスいただいた皆様のおかげで何とかなりそうです。
ありがとうございました!
(ろでっち) 2017/07/19(水) 22:31
VBAは初心者の私から見ても、かなり柔軟性にとんでいると思うのですが、何か理由でもあるんでしょうかね。
(ろでっち) 2017/07/19(水) 22:37
>PS:しかし、変数はPublicで定義してやると別プロシージャーでも使えるのに、 >なんでオブジェクト(SET)は使えないのかと不思議に思ってしまいます。
ちょっと、意味が分からないです。
(スカラー)変数とオブジェクト変数の何処が違うって言っているんでしょうか?
片や初期値(Longなら0、VariantならEmpty)、片やNothingになっているだけじゃないですか? 同じようなものと思うのですが?
スカラー変数だって、 こんなこと出来ないですよ? ↓ Public aa, bb aa = "AA" bb = "BB"
Sub Size()
End Sub
(半平太) 2017/07/19(水) 23:59
別視点から >PS:しかし、変数はPublicで定義してやると別プロシージャーでも使えるのに、 Publicは別「モジュール」で使える、のほうがしっくりきます 同一モジュールであれば、Dimでもいいのですから。 http://www.239-programing.com/excel-vba/basic/basic033.html
(稲葉) 2017/07/20(木) 02:00
定数と勘違いしているのだろうか?
(ねむねむ) 2017/07/20(木) 07:27
>定数と勘違いしているのだろうか?
そうですね。
>(ろでっち) 2017/07/19(水) 10:07
↑の書き方を見ると、定数と混同されているようですね。
あと、
>パブリックで変数を設定すると、モジュール内で共用の変数で使えるのは知っています。
↑これも誤解ですよね?
「publicで変数を宣言すると、他のモジュールからでもその変数を使用できる。」
ですね?
もう一回、
「変数 スコープ 適用範囲」等で検索されて認識を確かにしてください。
で、動けばいいというものないでしょう?
「なんで、これだとだめなの?」
というとこを突き詰めないと。。。
そこで、
>(ろでっち) 2017/07/19(水) 10:07
↑このコードは、どのモジュールに書いているのですか?
で、どうやってマクロを起動したいのですか?
(まっつわん) 2017/07/20(木) 08:16
Public ws1 As Worksheet 'これは変数宣言文だから、プロシジャ外に書くと共通変数になる
Sub test() Set ws1 = Worksheets("A") 'これは実行文だから、プロシジャ内にしか書けない Call testsub End Sub
Sub testsub() MsgBox ws1.Name 'ws1は共通変数だから、プロシジャ内で宣言無しで使える End Sub
ちなみに、この例ではws1はモジュール内共通変数です。 更に、標準モジュール等に Publicを付けて変数宣言すると、ブック内全体での共通変数(共通関数)になります。 VBAでは、大きく分けて3種類のスコープがあるということ。
(1)プロシジャ内だけの変数
(2)モジュール内共通変数
(3)ブック内共通変数
(???) 2017/07/20(木) 09:24
???さん > Public ws1 As Worksheet 'これは変数宣言文だから、プロシジャ外に書くと共通変数になる >この例ではws1はモジュール内共通変数です。 更に、標準モジュール等に Publicを付けて変数宣言 ということですが、Dim(Private)で宣言されたほうが、ろでっちさんも混乱されないかと思います。 (稲葉) 2017/07/20(木) 11:29
人の粗探しが得意ですみませーん。 自分の粗も簡単に見つけられたらいいのですが・・・。
ろでっちさんが質問してくれたら、うれしいですね。 (稲葉) 2017/07/20(木) 11:45
もう見てないのかな。。。ま、書いたので。。。
???さんとかぶってるかもですが書いちゃったので^^;
オブジェクトは「定数」として宣言できません。
なので「変数」として宣言し、後でプロシージャの中で「代入」という作業を書くことになります。
代入が出来てしまったら、「変数」でも「定数のように」扱うことができますね。
<標準モジュールに>
Option Explicit
'モジュールレベルで使用する変数の宣言
Private mWsh1 As Worksheet
Private mWsh2 As Worksheet
Private mWsh3 As Worksheet
Private mWsh4 As Worksheet
'メインのプロシージャ
Sub Size()
'オブジェクトの取得 Call GetObject
'条件分岐 If ws1.Range("A1").Value = "小" Then Call Mini ElseIf ws1.Range("A1").Value = "中" Then Call Midle ElseIf ws1.Range("A1").Value = "大" Then Call Big Else MsgBox "サイズ欄に「大」「中」「小」のいずれかを入力してください", vbCritical End If End Sub
'オブジェクトの取得
Private Sub GetObject()
With ThisWorkbook Set ws1 = .Worksheets("Sheet1") Set ws2 = .Worksheets("Sheet2") Set ws3 = .Worksheets("Sheet3") Set ws4 = .Worksheets("Sheet4") End With End Sub
'各プロシージャ
Private Sub Mini()
MsgBox mWsh2.Name End Sub Private Sub Middle() MsgBox mWsh3.Name End Sub Private Sub Big() MsgBox mWsh4.Name End Sub
'*************************************************
でも、この程度ならあえてプロシージャを分ける必要はないですよね。
参考までに、、、
Sub test()
Dim wsChoice As Sheets Dim wsInput As Worksheet Dim ix As Variant Dim sProm As String Dim lngBtn As Long
Set wsChoice = Worksheets(Array("Sheet2", "Sheet3", "Sheet4")) Set wsInput = Worksheets("Sheet1") sProm = "サイズ欄に「大」「中」「小」のいずれかを入力してください" lngBtn = vbCritical
On Error Resume Next ix = WorksheetFunction.Match(wsInput.Range("A1").Value, Array("小", "中", "大"), 0) On Error GoTo 0 If ix > 0 Then sProm = wsChoice(ix).Name lngBtn = vbOKOnly End If
MsgBox sProm, lngBtn End Sub
※ポイントは「同じことを2度書かない」です。
提示されたコードは、一連の流れの中で最終的には
Msgbox 〜
と同じことが4回出て来てます。
そういう時は変数を上手く使って1回にまとめます。
そうやって同じことを書かないようにするために、
共通の部品としてサブルーチンを用意するなら、
プロシージャを分ける方が効率的ですね^^
(まっつわん) 2017/07/20(木) 13:06
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.