こんにちは。#1、2、4、6、cjです。
#6で触れていた
> ...セル範囲の参照を容易に変更できる内容に書き換え...
やってみました。
その影響で処理の効率が落ちる面もあるので、その分、
他の部分を見直して補い、トータルでは、前より動作が軽くなっています。
先頭の2カ所だけ、セル範囲を指定すれば、
テーブルの位置を変更した場合にも容易に対応できます。
動作仕様はこれまで提示したものとまったく同じです。
まるまる差し替えで使ってください。
それでは、また。
' ' ==============================
Option Explicit
' ' ------------------------------
Const イベント範囲 As String = "C9:D20" ' 下位の入力規則を変更するイベント処理対象範囲の参照(2列)■要指定
Const マスタ左上 As String = "V9" ' マスタテーブル範囲の参照(データ部左上の単セル)■要指定
' ' ユーザー設定 ↑
' ' ------------------------------
' ' 固定 ↓
Const SHOGE As String = "分類"
Const SCOMMA As String = ","
' ' 参照設定する場合◆ : Microsoft Scripting Runtime
Private oDict(0 To 2) As Object ' As Scripting.Dictionary ' ◆
' ' ------------------------------
Sub 初期設定()
Call SetValid
End Sub
' ' ------------------------------
Private Sub SetValid(Optional ByVal Target As Range)
Dim sKey As String
Dim sList As String
Dim nFldPos As Long
Dim nOffset As Long
Dim i As Long
If Target Is Nothing Then
Set Target = Range(イベント範囲)
sKey = SHOGE ' "分類"
' nFldPos = 0& : nOffset = 0&
Else
sKey = Target.Value
nFldPos = Target.Column - Range(イベント範囲).Column + 1
nOffset = 1&
End If
Application.EnableEvents = False
On Error GoTo Exit_
If oDict(0) Is Nothing Then Call SetDict
With Target
For i = nFldPos To 2
nOffset = nOffset + 1&
sList = oDict(i)(sKey) ' ",A,B,C" ",DDD,EEE,FFF" ",1001,1002"
With .Columns(nOffset)
With .Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Formula1:=sList
' .IgnoreBlank = True
' .InCellDropdown = True
End With
sKey = Split(sList, SCOMMA)(1) ' "A" "DDD" "1001"
.Value = sKey
End With
Next i
End With
Exit_:
Application.EnableEvents = True
If Err Then MsgBox Err & Err.Description, vbExclamation
End Sub
' ' ------------------------------
Private Sub SetDict()
Dim mtxT()
Dim i As Long
With Range(マスタ左上)
mtxT = .Resize(.End(xlDown).Row - .Row + 1, 3).Value
End With
For i = 0 To 2
Set oDict(i) = CreateObject("Scripting.Dictionary")
' Set oDict(i) = New Scripting.Dictionary ' ◆
Next i
For i = 1 To UBound(mtxT)
If Not oDict(1).Exists(mtxT(i, 1)) Then
oDict(0)(SHOGE) = oDict(0)(SHOGE) & SCOMMA & mtxT(i, 1)
oDict(1)(mtxT(i, 1)) = oDict(1)(mtxT(i, 1)) & SCOMMA & mtxT(i, 2)
ElseIf Not oDict(2).Exists(mtxT(i, 2)) Then
oDict(1)(mtxT(i, 1)) = oDict(1)(mtxT(i, 1)) & SCOMMA & mtxT(i, 2)
End If
oDict(2)(mtxT(i, 2)) = oDict(2)(mtxT(i, 2)) & SCOMMA & mtxT(i, 3)
Next i
Erase mtxT()
'' ' < ツリー確認用
' Dim k1, k2, s2, v0, v1
' Debug.Print SHOGE, oDict(0)(SHOGE)
' k1 = oDict(1).Keys 'Split(SHOGE, SCOMMA)
' For Each v0 In k1
' Debug.Print , v0, oDict(1)(v0)
' k2 = Split(oDict(1)(v0), SCOMMA)
' For Each v1 In k2
' Debug.Print , , v1, oDict(2)(v1)
' Next
' Next
'' ' >
End Sub
' ' ------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Value = "" Then Exit Sub
If Intersect(Range(イベント範囲).Resize(, 2), Target) Is Nothing Then Exit Sub
Call SetValid(Target)
End Sub
' ' ------------------------------
Private Sub Worksheet_Deactivate()
Erase oDict()
End Sub
' ' ==============================
お礼
この度は、いろいろと希望に対応下さいましたおかげで、 大変使いやすい表が出来上がりました。 また、カスタマイズしたい部分はありますが、 今回とは別に質問を上げたいと思います。 本当にお世話になりました。