Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


10942 / 13644 ツリー ←次へ | 前へ→

【19035】同じような ponpon 04/10/19(火) 23:25 質問[未読]
【19037】Re:同じような ichinose 04/10/19(火) 23:39 発言[未読]
【19038】Re:同じような 追伸 ichinose 04/10/19(火) 23:47 発言[未読]
【19040】Re:同じような 追伸 ponpon 04/10/20(水) 0:07 発言[未読]
【19041】Re:同じような 追伸 [名前なし] 04/10/20(水) 0:14 回答[未読]
【19045】Re:同じような 追伸 ponpon 04/10/20(水) 0:36 お礼[未読]
【19047】Re:同じような 追伸 [名前なし] 04/10/20(水) 1:08 回答[未読]
【19050】Re:同じような 追伸 ponpon 04/10/20(水) 7:55 お礼[未読]
【19042】Re:同じような 追伸 ichinose 04/10/20(水) 0:15 発言[未読]
【19043】Re:同じような 追伸 ponpon 04/10/20(水) 0:18 発言[未読]
【19044】Re:同じような 追伸 ichinose 04/10/20(水) 0:24 回答[未読]
【19046】Re:同じような 追伸 ponpon 04/10/20(水) 0:45 お礼[未読]
【19048】Re:同じような 追伸 ichinose 04/10/20(水) 1:10 発言[未読]
【19049】Re:同じような 追伸 ichinose 04/10/20(水) 1:22 発言[未読]
【19051】Re:同じような 追伸 ponpon 04/10/20(水) 8:09 お礼[未読]

【19035】同じような
質問  ponpon  - 04/10/19(火) 23:25 -

引用なし
パスワード
   こんばんは。PONPONです。
 またまたお世話になります。明日が台風のため(今年4日目です。先のことを考えると不安ですが・・・)休みになったので(もちろん職員は年休ですよ)、今まで書いていたコードを見直しています。

以下質問です。
 職員用に年間時間割の自動作成を作っています。
 コードを見てみると、参照するセルが違うだけだったり、参照するシートが違うだけだったりするコードがたくさんあります。
 ひな形のコード(引数付き)を作り、引数にセルを入力することで、同じようなコードを少なくしたいと思い挑戦しています。
 XXXXX(i AS InTger,j AS InTeger)とし、コードの参照セルをCells(i,j)とすることで、何とかうまくできました。
   Call XXXXX(2,5)  とか  Call XXXXX(4,8)
(本当に正しいかどうかはわかりませんが、一応思った通りに動作しています。やったね!!)
 しかし、引数にWorksheetや文字をいれて同じようにしても、「型が一致しません」とエラーが発生してしまいます。

 以下コードの説明
 各種設定シートに、年月日入力欄とその横にあるチェックボックス6個(1校時から6校時まで)を設定しています。
 行事設定シートに、たとえば、年月日を入力し、1校時、2校時をチェックし、コマンドボタンをクリックすると、年度時数(全)シートにある同じ年月日の年間時間割の1校時時2校時にに「行」を入力するというものです。
 欠時設定シートでは同じように「欠」を、その他設定では、特定セル上の任意の一文字を というものです。 
 これを各種設定(ABC AS Worksheet, MOJI AS String)
というひな形を作り、シートと文字を指定することで、簡略化できないものかと考えています。
   Call 各種設定(行事設定,行) こんなふうに
こんな説明でわかりますか? うまく伝わるといいけど・・・
 よろしくお願いします。


Sub 行事設定()
  Dim TATE_G As Integer
  Dim YOKO_G As Integer
  Dim TATE_N As Integer
  Dim N As Integer
  Dim 色番号 As Variant
  Dim KYMD As Date
  Dim GYMD As Date


For TATE_G = 5 To 34
 For YOKO_G = 1 To 6
  If Worksheets("行事設定").Cells(TATE_G, 35).Value <> ""  Then
          ↑ここが違うだけ 
  GYMD = Worksheets("行事設定").Cells(TATE_G, 35).Value
             ↑  
   If Worksheets("行事設定").Cells(TATE_G, YOKO_G + 35).Value = True Then
             ↑
    For TATE_N = 4 To 85
    For N = 3 To 31 Step 7
     If Worksheets("年度時数(全)").Cells(TATE_N, N).Value <> "" Then
      KYMD = Worksheets("年度時数(全)").Cells(TATE_N, N).Value
      If Format(GYMD, "YYYY/MM/DD") = Format(KYMD, "YYYY/MM/DD") Then
       Sheets("年度時数(全)").Select
       Range(Cells(TATE_N, YOKO_G + N), Cells(TATE_N, _
                         YOKO_G + N)).Select
        色番号 = Selection.Interior.ColorIndex
        If 色番号 = 15 Or 色番号 = 38 Or 色番号 = 48 Then
        ElseIf Sheets("年度時数(全)").Cells(TATE_N, _   
        YOKO_G+ N).Interior.ColorIndex = 15 Then
        Else
        Sheets("年度時数(全)").Cells(TATE_N, _
                    YOKO_G + N).Value = "行"
                                 ↑ 
                              ここの文字が違うだけ
        Worksheets("年度時数(全)").Range(Cells(TATE_N, _
             YOKO_G + N), Cells(TATE_N, YOKO_G + N)).Select
        Selection.Font.ColorIndex = 3
        Selection.Font.Bold = True
        Selection.Interior.ColorIndex = 35
        End If
       End If
      End If
     Next
    Next
    End If
   End If
  Next
 Next
End sub 
 

【19037】Re:同じような
発言  ichinose  - 04/10/19(火) 23:39 -

引用なし
パスワード
   ▼ponpon さん:
こんばんは。

>こんばんは。PONPONです。
> またまたお世話になります。明日が台風のため(今年4日目です。先のことを考えると不安ですが・・・)休みになったので(もちろん職員は年休ですよ)、今まで書いていたコードを見直しています。
>
>以下質問です。
> 職員用に年間時間割の自動作成を作っています。
> コードを見てみると、参照するセルが違うだけだったり、参照するシートが違うだけだったりするコードがたくさんあります。
> ひな形のコード(引数付き)を作り、引数にセルを入力することで、同じようなコードを少なくしたいと思い挑戦しています。

> XXXXX(i AS InTger,j AS InTeger)とし、コードの参照セルをCells(i,j)とすることで、何とかうまくできました。
>   Call XXXXX(2,5)  とか  Call XXXXX(4,8)
>(本当に正しいかどうかはわかりませんが、一応思った通りに動作しています。やったね!!)
> しかし、引数にWorksheetや文字をいれて同じようにしても、「型が一致しません」とエラーが発生してしまいます。
>
> 以下コードの説明
> 各種設定シートに、年月日入力欄とその横にあるチェックボックス6個(1校時から6校時まで)を設定しています。
> 行事設定シートに、たとえば、年月日を入力し、1校時、2校時をチェックし、コマンドボタンをクリックすると、年度時数(全)シートにある同じ年月日の年間時間割の1校時時2校時にに「行」を入力するというものです。
> 欠時設定シートでは同じように「欠」を、その他設定では、特定セル上の任意の一文字を というものです。

 
> これを各種設定(ABC AS Worksheet, MOJI AS String)
          ↑ このようにパラメータを設定したならば
>   Call 各種設定(行事設定,行) こんなふうに

 call 各種設定(Worksheets("行事設定"),"行")

というように型を合わせて引数を指定しなければなりませんよ!!

【19038】Re:同じような 追伸
発言  ichinose  - 04/10/19(火) 23:47 -

引用なし
パスワード
   >> これを各種設定(ABC AS Worksheet, MOJI AS String)
ABCやMOJIが「各種設定」というプロシジャーの入力データ用にのみ使用の
パラメータならば、

Sub 各種設定(ByVal ABC As Worksheet, ByVal MOJI As String)

というように宣言した方がよいかもしれません。
(私もよく忘れますが・・・)
>>   Call 各種設定(行事設定,行) こんなふうに
>
> call 各種設定(Worksheets("行事設定"),"行")
>
>というように型を合わせて引数を指定しなければなりませんよ!!

【19040】Re:同じような 追伸
発言  ponpon  - 04/10/20(水) 0:07 -

引用なし
パスワード
   ▼ichinose さん:
 いつもありがとうございます。
今、試しています。もうちょっとお待ちくださいませ。どもども。
その前にちょっと質問。
If Worksheets("行事設定").Cells(TATE_G, 43).Value
  ↓
If ABC.Cells(TATE_G, 43).Value
と、していいんですよね?

>>> これを各種設定(ABC AS Worksheet, MOJI AS String)
>ABCやMOJIが「各種設定」というプロシジャーの入力データ用にのみ使用の
>パラメータならば、
>
>Sub 各種設定(ByVal ABC As Worksheet, ByVal MOJI As String)
>
>というように宣言した方がよいかもしれません。
>(私もよく忘れますが・・・)
>>>   Call 各種設定(行事設定,行) こんなふうに
>>
>> call 各種設定(Worksheets("行事設定"),"行")
>>
>>というように型を合わせて引数を指定しなければなりませんよ!!

【19041】Re:同じような 追伸
回答  [名前なし]  - 04/10/20(水) 0:14 -

引用なし
パスワード
   ▼ponpon さん:
引数をシート名にしちゃったほうがよいのでは?
Sub 各種設定(ByVal SheetName As String, ByVal MOJI As String)

If Worksheets(SheetName).Cells(TATE_G, 43).Value


呼び出し方はこんな感じで。
Call 各種設定("行事設定","行")

【19042】Re:同じような 追伸
発言  ichinose  - 04/10/20(水) 0:15 -

引用なし
パスワード
   ▼ponpon さん:


>今、試しています。もうちょっとお待ちくださいませ。どもども。
>その前にちょっと質問。
>If Worksheets("行事設定").Cells(TATE_G, 43).Value
>  ↓
>If ABC.Cells(TATE_G, 43).Value
>と、していいんですよね?
大丈夫です。

【19043】Re:同じような 追伸
発言  ponpon  - 04/10/20(水) 0:18 -

引用なし
パスワード
   ▼ichinose さん:
Sub 各種文字設定(ByVal ABC As Worksheets, ByVal MOJI As String)
このように設定して、
  Call 各種文字設定(Worksheets("行事設定"), "行")
のように呼び出しましたが、やはり「実行時エラー。型が一致しません」とエラー
になってしまいます。
 どうしてかな?
 どこか間違ったのでしょうか?


>>> これを各種設定(ABC AS Worksheet, MOJI AS String)
>ABCやMOJIが「各種設定」というプロシジャーの入力データ用にのみ使用の
>パラメータならば、
>
>Sub 各種設定(ByVal ABC As Worksheet, ByVal MOJI As String)
>
>というように宣言した方がよいかもしれません。
>(私もよく忘れますが・・・)
>>>   Call 各種設定(行事設定,行) こんなふうに
>>
>> call 各種設定(Worksheets("行事設定"),"行")
>>
>>というように型を合わせて引数を指定しなければなりませんよ!!

【19044】Re:同じような 追伸
回答  ichinose  - 04/10/20(水) 0:24 -

引用なし
パスワード
   ▼ponpon さん:
>Sub 各種文字設定(ByVal ABC As Worksheets, ByVal MOJI As String)
                   ↑Worksheetです。「s」要りません
>このように設定して、
>  Call 各種文字設定(Worksheets("行事設定"), "行")
>のように呼び出しましたが、やはり「実行時エラー。型が一致しません」とエラー
>になってしまいます。
> どうしてかな?
> どこか間違ったのでしょうか?
>
>
>>>> これを各種設定(ABC AS Worksheet, MOJI AS String)
>>ABCやMOJIが「各種設定」というプロシジャーの入力データ用にのみ使用の
>>パラメータならば、
>>
>>Sub 各種設定(ByVal ABC As Worksheet, ByVal MOJI As String)
>>
>>というように宣言した方がよいかもしれません。
>>(私もよく忘れますが・・・)
>>>>   Call 各種設定(行事設定,行) こんなふうに
>>>
>>> call 各種設定(Worksheets("行事設定"),"行")
>>>
>>>というように型を合わせて引数を指定しなければなりませんよ!!

【19045】Re:同じような 追伸
お礼  ponpon  - 04/10/20(水) 0:36 -

引用なし
パスワード
   ▼[名前なし] さん:

バッチリうまく走りました。
これで、少し引数付きのプロシージャについて
わかったような気になりました。
 Byvalだと参照渡しだったですかね。ヘルプを呼んでも今一よくわかりません。
参照渡しだと、元プロシージャの値が参照先のプロシージャで引数が変更されても
変更しない。実数渡しだと元プロシージャの値が変更されると解説されていますが、
具体的にはどんなことなのでしょうか??
 よければ教えていただけないでしょうか。


>引数をシート名にしちゃったほうがよいのでは?
>Sub 各種設定(ByVal SheetName As String, ByVal MOJI As String)
>
>If Worksheets(SheetName).Cells(TATE_G, 43).Value
>
>
>呼び出し方はこんな感じで。
>Call 各種設定("行事設定","行")

【19046】Re:同じような 追伸
お礼  ponpon  - 04/10/20(水) 0:45 -

引用なし
パスワード
   ▼ichinose さん:
>>Sub 各種文字設定(ByVal ABC As Worksheets, ByVal MOJI As String)
>                   ↑Worksheetです。「s」要りません


うまく走りました。たったこれだけで走らないんですね。考えてみれば、「s」をつけるとコレクション?に成るんですよね??かな。
一枚のシートだから「s」はいらない。」考えてみると当たり前のことですよね。
いつもいつも初歩的な質問に回答をありがとうございます。

「名前なし」さんにも質問したのですが。実数渡しと参照渡し、解説の意味は何となくわかるのですが、具体的な例としてどんなことがあるのでしょうか。
 よかったら教えていただきたいのですが・・厚かましく申し訳ありません。

【19047】Re:同じような 追伸
回答  [名前なし]  - 04/10/20(水) 1:08 -

引用なし
パスワード
   ▼ponpon さん:
ByValだと「値渡し」、ByRefだと「参照渡し」です。

Sub Main()
Dim Test1 As Long
Dim Test2 As Long

Test1 = 100
Test2 = 100

Call Test(Test1, Test2)
MsgBox Test1 & "/" & Test2

End Sub

Sub Test(ByVal a As Long, ByRef b As Long)
 a = a * 1.05
 b = b * 1.05
End Sub

として、Mainを実行してみてください。
bの方だけ値が変わると思います。
このように、引数に変数を使用し、プロシージャの中で引数に代入すると、
変数の中身まで変わってしまうのがByRef(参照渡し)です。

【19048】Re:同じような 追伸
発言  ichinose  - 04/10/20(水) 1:10 -

引用なし
パスワード
   ▼ponpon さん:
>▼ichinose さん:
>>>Sub 各種文字設定(ByVal ABC As Worksheets, ByVal MOJI As String)
>>                   ↑Worksheetです。「s」要りません
>
>
>うまく走りました。たったこれだけで走らないんですね。考えてみれば、「s」をつけるとコレクション?に成るんですよね??かな。
>一枚のシートだから「s」はいらない。」考えてみると当たり前のことですよね。
>いつもいつも初歩的な質問に回答をありがとうございます。
>
>「名前なし」さんにも質問したのですが。実数渡しと参照渡し、解説の意味は何となくわかるのですが、具体的な例としてどんなことがあるのでしょうか。
> よかったら教えていただきたいのですが・・厚かましく申し訳ありません。
値渡しと参照渡しについて。
確認したわけではないのでたぶんの話として。
sub test()
 dim x as long
 dim y as long
 x=1
 y=2
 Call aaa(x,y)
' 制御を戻す番地 
 msgbox x
end sub
'========================
sub aaa(a as long,b as long)
a=a+b
end sub

というコードがあったとします。
この場合、参照渡しです。

Call a(a,b)

が実行された時点でスタックと呼ばれるメモリ領域が作成されます。
ここには、プロシジャーaaaの実行が終了したとき制御を戻す番地やパラメータの
番地が格納されます。
プロシジャーaaaでは、このスタックの情報を取得して処理が行われます。
参照渡しの場合は、スタックからパラメータa,bの番地(アドレス)を取得して後、
実際のa,bが存在する番地から値を取得します。
よって、この場合、
Msgbox x
で「3」が表示されます。

sub aaa(byval a as long,byval b as long)
  a=a+b
end sub

この場合は、値渡しになります。
値渡しの場合、スタックには、a,bの番地ではなく、指定された値が格納されます。
この場合、
a=a+bの結果である「3」は、スタック内に格納されるはずなんです。
よって、x,yには、演算の結果は反映されません。
だって、プロシジャーaaaが終了してtestに戻ったときには、スタックは
解放されてしまいますから・・・。

つまり、

msgbox xは、「1」のまんまです。

でも、参照渡しより、パラメータを取得するのにスタック内のアクセスのみで済むので処理が速いとされています。


たぶん、こんなしくみになっていると思いますが・・・。

【19049】Re:同じような 追伸
発言  ichinose  - 04/10/20(水) 1:22 -

引用なし
パスワード
   >>>>Sub 各種文字設定(ByVal ABC As Worksheets, ByVal MOJI As String)
>>>                   ↑Worksheetです。「s」要りません
>>
>>
>>うまく走りました。たったこれだけで走らないんですね。考えてみれば、「s」をつけるとコレクション?に成るんですよね??かな。
>>一枚のシートだから「s」はいらない。」考えてみると当たり前のことですよね。
>>いつもいつも初歩的な質問に回答をありがとうございます。
>>
>>「名前なし」さんにも質問したのですが。実数渡しと参照渡し、解説の意味は何となくわかるのですが、具体的な例としてどんなことがあるのでしょうか。
>> よかったら教えていただきたいのですが・・厚かましく申し訳ありません。
>値渡しと参照渡しについて。
>確認したわけではないのでたぶんの話として。
>sub test()
> dim x as long
> dim y as long
> x=1
> y=2
> Call aaa(x,y)
>' 制御を戻す番地 
> msgbox x
>end sub
>'========================
>sub aaa(a as long,b as long)
> a=a+b
>end sub
>
>というコードがあったとします。
>この場合、参照渡しです。
>
Call aaa(x,y)
訂正です
>
>が実行された時点でスタックと呼ばれるメモリ領域が作成されます。
>ここには、プロシジャーaaaの実行が終了したとき制御を戻す番地やパラメータの
>番地が格納されます。
>プロシジャーaaaでは、このスタックの情報を取得して処理が行われます。
>参照渡しの場合は、スタックからパラメータa,bの番地(アドレス)を取得して後、
>実際のa,bが存在する番地から値を取得します。
>よって、この場合、
>Msgbox x
>で「3」が表示されます。
>
>sub aaa(byval a as long,byval b as long)
>  a=a+b
>end sub
>
>この場合は、値渡しになります。
>値渡しの場合、スタックには、a,bの番地ではなく、指定された値が格納されます。
>この場合、
>a=a+bの結果である「3」は、スタック内に格納されるはずなんです。
>よって、x,yには、演算の結果は反映されません。
>だって、プロシジャーaaaが終了してtestに戻ったときには、スタックは
>解放されてしまいますから・・・。
>
>つまり、
>
>msgbox xは、「1」のまんまです。
>
>でも、参照渡しより、パラメータを取得するのにスタック内のアクセスのみで済むので処理が速いとされています。
>
>
>たぶん、こんなしくみになっていると思いますが・・・。

【19050】Re:同じような 追伸
お礼  ponpon  - 04/10/20(水) 7:55 -

引用なし
パスワード
   ▼[名前なし] さん:
 おはようございます。昨日は途中でくたばってしまいました。

>ByValだと「値渡し」、ByRefだと「参照渡し」です。
   ↑
 逆でしたね。単語も間違ってるし・・・いい加減な記憶ですね。


 試してみました。変数の中身まで変わってしまうのですね。
 ichinoseさんの回答とあわせて読ませていただきました。
 私のように初心者は、変数の中身まで変わってしまったらとても困ってしまいます。
 しかし、次から次に変数の中身を変えて利用するロジックでは有効な気がします。
 丁寧な回答をありがとうございます。
  ↓
>Sub Main()
>Dim Test1 As Long
>Dim Test2 As Long
>
>Test1 = 100
>Test2 = 100
>
>Call Test(Test1, Test2)
>MsgBox Test1 & "/" & Test2
>
>End Sub
>
>Sub Test(ByVal a As Long, ByRef b As Long)
> a = a * 1.05
> b = b * 1.05
>End Sub
>
>として、Mainを実行してみてください。
>bの方だけ値が変わると思います。
>このように、引数に変数を使用し、プロシージャの中で引数に代入すると、
>変数の中身まで変わってしまうのがByRef(参照渡し)です。

【19051】Re:同じような 追伸
お礼  ponpon  - 04/10/20(水) 8:09 -

引用なし
パスワード
   ▼ichinose さん:
おはようございます。
昨日は(あっ今日か)、丁寧な回答ありがとうございました。途中でダウンしてしまいました。失礼しました。
 無事コードも走り、おかげで、すっきりしたものにどんどん成っています。
ここの掲示板で学習したことで、見やすいコードに成っていることが自分でもわかります。(ただ、ベタ書きでないので、後で見ると何のこと?とならないかが心配です。)
 以下について、「名前なし」さんの回答と併せて読ませていただきました。byvalと
byrefの違い(記憶違いも)何となく、わかったような気がします。省略すると参照渡しに成ってしまうのですね。気をつけたいと思います。
 ありがとうございました。 

>>値渡しと参照渡しについて。
>>確認したわけではないのでたぶんの話として。
>>sub test()
>> dim x as long
>> dim y as long
>> x=1
>> y=2
>> Call aaa(x,y)
>>' 制御を戻す番地 
>> msgbox x
>>end sub
>>'========================
>>sub aaa(a as long,b as long)
>> a=a+b
>>end sub
>>
>>というコードがあったとします。
>>この場合、参照渡しです。
>>
>Call aaa(x,y)
>訂正です
>>
>>が実行された時点でスタックと呼ばれるメモリ領域が作成されます。
>>ここには、プロシジャーaaaの実行が終了したとき制御を戻す番地やパラメータの
>>番地が格納されます。
>>プロシジャーaaaでは、このスタックの情報を取得して処理が行われます。
>>参照渡しの場合は、スタックからパラメータa,bの番地(アドレス)を取得して後、
>>実際のa,bが存在する番地から値を取得します。
>>よって、この場合、
>>Msgbox x
>>で「3」が表示されます。
>>
>>sub aaa(byval a as long,byval b as long)
>>  a=a+b
>>end sub
>>
>>この場合は、値渡しになります。
>>値渡しの場合、スタックには、a,bの番地ではなく、指定された値が格納されます。
>>この場合、
>>a=a+bの結果である「3」は、スタック内に格納されるはずなんです。
>>よって、x,yには、演算の結果は反映されません。
>>だって、プロシジャーaaaが終了してtestに戻ったときには、スタックは
>>解放されてしまいますから・・・。
>>
>>つまり、
>>
>>msgbox xは、「1」のまんまです。
>>
>>でも、参照渡しより、パラメータを取得するのにスタック内のアクセスのみで済むので処理が速いとされています。
>>
>>
>>たぶん、こんなしくみになっていると思いますが・・・。

10942 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free