Excel VBA質問箱 IV

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

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


7204 / 13646 ツリー ←次へ | 前へ→

【40504】シートモジュールのクラス化 ハナ 06/7/15(土) 9:11 質問[未読]
【40505】Re:シートモジュールのクラス化 やっちん 06/7/15(土) 9:53 発言[未読]
【40507】Re:シートモジュールのクラス化 neptune 06/7/15(土) 10:48 回答[未読]
【40567】Re:シートモジュールのクラス化 ハナ 06/7/18(火) 11:23 お礼[未読]
【40516】Re:シートモジュールのクラス化 asahi 06/7/15(土) 14:12 回答[未読]
【40518】Re:シートモジュールのクラス化 Kein 06/7/15(土) 15:35 回答[未読]

【40504】シートモジュールのクラス化
質問  ハナ  - 06/7/15(土) 9:11 -

引用なし
パスワード
   いつも参考にさせていただいてます。
XLSで注文書を作成するプログラムを作っているのですが
複数のシート(SH3,SH4,SH5)で全く同じシートモジュールを記述していて
とても効率が悪い感じがするんです。(下記のコードです)
 動作としては
   ・シートがACTIVEになったら
      シート保護をかける
      F4キーに標準モジュール記載のルーチン(SND)を割り当てる
   ・セルの値が変化したら
      1列目にコードを入力したら2列目にDBから呼び出した
      仕入先名を表示する
 というようなものです
****
Private Sub Worksheet_Activate()
  ActiveSheet.Unprotect
  ActiveSheet.Protect DrawingObjects:=True, Contents:=True,     Scenarios:=True
  ActiveSheet.EnableSelection = xlUnlockedCells
  ActiveSheet.Protect UserInterfaceOnly:=True
  Application.OnKey "{F4}", "SND" 
End Sub
********

Private Sub Worksheet_Change(ByVal Target As Range)
Dim SMCODE As Variant

On Error GoTo ER
With Target
  If .Column = 1 Then
'
    If .Value = "" Then
      .Interior.ColorIndex = xlNone
      .Offset(0, 1).Value = ""
      Exit Sub
    End If
'
    Set Con = New ADODB.Connection
    SMCODE = .Value
    Con.Open "DSN=TEST"
    Con.Execute ("SET NAMES sjis")
    msql = "select SNAME FROM SM01 "
    msql = msql & " WHERE SCD = '" & SMCODE & " ';"
    Set Rst = New ADODB.Recordset
    Rst.Open msql, Con
'
    If Rst.EOF Then
      .Interior.ColorIndex = 3
      .Offset(0, 1).Value = ""
      Exit Sub
    End If
'
    .Interior.ColorIndex = xlNone
    .Offset(0, 1).Value = Rst!SNAME
    Rst.Close
    Set Rst = Nothing
    Con.Close
    Set Con = Nothing
  End If
  If .Column = 11 Then
    .Offset(, 1) = Val(.Offset(, -1)) + Val(.Value)
  End If
End With
Exit Sub
ER:
  Exit Sub
End Sub
*******
全く同じ記載なので、変数だけ与えてクラスモジュールでなんとかならないかと思って、いろいろ調べたのですが、なかなか資料がみつからないので困っています
クラスモジュール以外でも、こうした重複記載を改善する手立てがありましたら
教えていただけないでしょうか。
どうぞよろしくお願いします。

【40505】Re:シートモジュールのクラス化
発言  やっちん  - 06/7/15(土) 9:53 -

引用なし
パスワード
   ▼ハナ さん:
こんにちは。
処理自体を標準モジュールに作って
それぞれのシートモジュールからそれを呼び出してはどうでしょうか。

【40507】Re:シートモジュールのクラス化
回答  neptune  - 06/7/15(土) 10:48 -

引用なし
パスワード
   ▼ハナ さん:
>いつも参考にさせていただいてます。
>XLSで注文書を作成するプログラムを作っているのですが
>複数のシート(SH3,SH4,SH5)で全く同じシートモジュールを記述していて
>とても効率が悪い感じがするんです。(下記のコードです)
> 動作としては
>   ・シートがACTIVEになったら
>      シート保護をかける
>      F4キーに標準モジュール記載のルーチン(SND)を割り当てる
>   ・セルの値が変化したら
>      1列目にコードを入力したら2列目にDBから呼び出した
>      仕入先名を表示する
> というようなものです
クラスモジュール内に必要な処理を書き足せば良いです。
いちばん簡単な例です。
多分分からなかったところは WithEvents ?
詳細はHelp、他のサイトの解説などで研究してください。

'//////標準モジュール////////
Option Explicit

Private clsSheet(1) As Class1

Sub Test()
  'クラスがシートのイベント処理出来るようにする。
  Set clsSheet(0) = New Class1
  Set clsSheet(0).evtSheet = Worksheets("Sheet1")
  Set clsSheet(1) = New Class1
  Set clsSheet(1).evtSheet = Worksheets("Sheet2")
End Sub

Sub TestEnd()
  Set clsSheet(0) = Nothing
  Set clsSheet(1) = Nothing
End Sub
'////////////////////////////////////

'クラスモジュール モジュール名「Class1」
Option Explicit

Private WithEvents mSheet As Worksheet

Property Set evtSheet(pSheet As Worksheet)
  Set mSheet = pSheet
End Property

Property Get evtSheet() As Worksheet
  Set evtSheet = mSheet
End Property

Private Sub mSheet_Activate()
  MsgBox mSheet.Name
End Sub
'/////////////////////////////////

>全く同じ記載なので、変数だけ与えてクラスモジュールでなんとかならないかと思って、いろいろ調べたのですが、なかなか資料がみつからないので困っています
そのものズバリはないですよ。
ただ、昔と違って今はクラスモジュールのサンプルはたくさんあります。
あったでしょう?
その概念を理解に勤めましょう。

【40516】Re:シートモジュールのクラス化
回答  asahi  - 06/7/15(土) 14:12 -

引用なし
パスワード
   >全く同じ記載なので、変数だけ与えてクラスモジュールでなんとかならないかと
>思って、いろいろ調べたのですが、なかなか資料がみつからないので困っています

シートモジュールのクラス化と言う事でしたら、元々準備されています。
それはThisWorkbookモジュールです。
各シートモジュールにはコードを一切記述しないで、
単にThisWorkbookモジュールに記述することで事足りると思います。

【40518】Re:シートモジュールのクラス化
回答  Kein  - 06/7/15(土) 15:35 -

引用なし
パスワード
   >複数のシート(SH3,SH4,SH5)で全く同じシートモジュールを記述していて
>とても効率が悪い
誰かがレスしてくれているように、ThisWorkbookモジュールにあるイベント
を使うと、全シート対象のイベントが使えます。例えば

Private Sub Workbook_SheetActivate(ByVal Sh As Object)

というタイトルのマクロなら、引数 Sh には自動的にアクティブシートが
格納されますから

Select Case Sh.Name
  Case "SH3", "SH4", "SH5"
   何かの処理
End Select

などとシート名を判定して、処理を行うかどうかを分岐すれば良いのです。
同様にセル入力イベントの方も

Private Sub Workbook_SheetChange(ByVal Sh As Object,
ByVal Target As Range)

と、シートレベルのイベントと違う点は、引数 Sh の存在だけですから、
冒頭にシート名による条件分岐のコードを持ってくるところも同じですね。

【40567】Re:シートモジュールのクラス化
お礼  ハナ  - 06/7/18(火) 11:23 -

引用なし
パスワード
   ▼ご回答いただいたみなさん:
アドバイスありがとうございます。
お礼が遅くなって申し訳ありません。なかなか上手くいかなかったもので
ご報告が遅れてしまって・・・・。
neptuneさんにいただいたクラスの方法を軸にして
asahiさんやkeinさんにアドバイスいただいたThisWorkbookと
組み合わせてプログラムを作成して上手くいきました。
 ここで疑問が残るのは、どちらが効率の良い方法なのか?ですが
それぞれの状況で変わるのでしょうか・・・
これから、その辺も勉強していきます。
なにはともあれ、皆さん、ご指導ありがとうございました

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