すみません。
下記の様に、データ入力後のセルを動かせるVBAを考えています。
この動きは1回分で、次はF20から始まります。
F10,H10,F11,H11,O10,Q10,O11,Q11,X10,Z10,X11,Z11,AG10,AI10,AG11,AI11,AP10,AR10,AP11,AR11,AZ10,BC10,AZ11,BC11,
F12,H12,F13,H13,O12,Q12,O13,Q13,X12,Z12,X13,Z13,AG12,AI12,AG13,AI13,AP12,AR12,AP13,AR13,AZ12,BC12,AZ13,BC13,
F14,H14,F15,H15,O14,Q14,O15,Q15,X14,Z14,X15,Z15,AG14,AI14,AG15,AI15,AP14,AR14,AP15,AR15,AZ14,BC14,AZ15,BC15,
F16,H16,F17,H17,O16,Q16,O17,Q17,X16,Z16,X17,Z17,AG16,AI16,AG17,AI17,AP16,AR16,AP17,AR17,AZ16,BC16,AZ17,BC17,
F18,H18,F19,H19,O18,Q18,O19,Q19,X18,Z18,X19,Z19,AG18,AI18,AG19,AI19,AP18,AR18,AP19,AR19,AZ18,BC18,AZ19,BC19,
アドバイスをお願いいたします。
No.3ベストアンサー
- 回答日時:
#1-2です。
補足・お礼、拝見しました。> 自分なりに理解に努力しましたが、難しいので理解できませんでした。
> でも、少しずつ出来るよう続けていこうと思います。
ということなので、少しでも理解の援けになるよう解説を書いてみました。
また、少しでも解り易いものになるよう、再度書き換えました(動作仕様は全く一緒)。
すぐに解ろうとしないでも、少しずつ、時間が経てば深まるものに期待していていいです。
無理して返事しないで構いませんから、またいつかここで、お会いしましょう。
前提として、相対参照の仕方を確認してみて下さい。
Range("A10").Range("F1").Select ' → F10 を選択
Range("A10").Range("H2").Select ' → H11
Range("A10").Range("BC2").Select ' → BC11
Range("A12").Range("F1").Select ' → F12
Range("A12").Range("H2").Select ' → H13
Range("A12").Range("BC2").Select ' → BC13
上の相対参照の例に照らして考えると、
'10''12' の部分を
Dim nLevelRow As Long ' 各ブロック毎の相対参照基準行位置(10,12,14,...)"F11"なら10,"BC11"なら10→12
で表現します。
"F1"H1""BC2"... の部分を相対参照セルアドレスとして
' ' セル選択の順番を定義した内の筆頭にあるセルアドレス:"F1"
Private sRelativeRefOrg As String
Dim sRelativeRefPrev As String ' 値変更されたセルのアドレス('A列基準行セル'への相対参照)
Dim sRelativeRefNext As String ' 次に選択するべきセルのアドレスを('A列基準行セル'への相対参照)
等のように表現しています。
処理の流れとしては、
F10(Range("A10").Range("F1"))の値が変更されたなら。
H10(Range("A10").Range("H1"))を選択する、という場合
"F1"を辞書で調べると"H1"が返ってくる、というようなこと(対応付け)
をする目的で、Dictinary(辞書)オブジェクトを使っています。
BC11(Range("A10").Range("BC2"))の値が変更されたなら。
F12(Range("A12").Range("F1"))を選択する、という場合
"BC2"を辞書で調べると"F1"が返ってくる。"F1"返ってきたら、
基準行位置(10)を次のブロックの基準行位置(12)に変更する。
技術的なポイントとしてその他、
イベントプロシージャ(Worksheet_Change)の基本的な扱い
配列変数やSplit関数の基本的な扱い
等もチェックしてみて下さい。
以下、差し替えてお使い下さい。
' ' ///
Option Explicit
' ' ' 相対参照で セル選択の順番を定義(配列の元データ)(セル範囲参照文字列)
Const SREF = "F1,H1,F2,H2,O1,Q1,O2,Q2,X1,Z1,X2,Z2,AG1,AI1,AG2,AI2,AP1,AR1,AP2,AR2,AZ1,BC1,AZ2,BC2"
' ' 値変更されたセルアドレスを'A列基準行セル'への相対参照で渡すと、
' ' 次に選択するべきセルのアドレスを'A列基準行セル'への相対参照で返す
' ' Dictinary(辞書)オブジェクト
Private oDict As Object ' Scripting.Dictionary
' ' セル選択の順番を定義した内の筆頭にあるセルアドレス:"F1"
' ' (次に選択するべき相対参照セルアドレスが"F1"に一致したならば、
' ' 基準行位置を次のブロックの基準行位置に変更する為に必要)
Private sRelativeRefOrg As String
Private Sub Worksheet_Change(ByVal Target As Range) ' 値変更時に発生するイベント
Dim arrRelativeRef() As String ' 定義されたセル選択の順番を格納する配列(相対参照のアドレス)
Dim sRelativeRefPrev As String ' 値変更されたセルのアドレス('A列基準行セル'への相対参照)
Dim sRelativeRefNext As String ' 次に選択するべきセルのアドレスを('A列基準行セル'への相対参照)
Dim nLevelRow As Long ' 各ブロック毎の相対参照基準行位置(10,12,14,...)"F11"なら10,"BC11"なら10→12
Dim nUBound As Long ' 配列の大きさ(要素数より1少ない数)
Dim i As Long ' ループ用
If Target.Count > 1 Then Exit Sub ' 値変更されたセルの数が1より大きければ処理を抜ける
If Target.Row < 10 Then Exit Sub ' 値変更されたセルの行位置が10未満ならば処理を抜ける
' ' 値変更されたセルが定義されたセルの列に該当しなければ処理を抜ける
If Intersect(Target, Range(SREF).EntireColumn) Is Nothing Then Exit Sub
' ' Dictinary(辞書)オブジェクトが未設定なら(初めてこの記述を実行する時)
' ' Dictinary(辞書)オブジェクトの実体を作成し、格納する
' ' F1→H1,H1→F2,F2→H2,...BC2→(次のブロックの)F1、のように対応関係を呼び出す為のもの
If oDict Is Nothing Then
Set oDict = CreateObject("Scripting.Dictionary") ' インスタンス生成
arrRelativeRef() = Split(SREF, ",") ' 定義されたセル選択の順番(相対参照のアドレス)を配列に格納
' ' セル選択の順番を定義した内の筆頭にあるセルアドレス:"F1"
' ' (次に選択するべき相対参照セルアドレスが"F1"に一致したならば、
' ' 基準行位置を次のブロックの基準行位置に変更する為に必要)
sRelativeRefOrg = arrRelativeRef(0)
nUBound = UBound(arrRelativeRef()) ' 配列の大きさ(要素数より1少ない数)
For i = 0 To nUBound - 1
oDict(arrRelativeRef(i)) = arrRelativeRef(i + 1) ' 辞書に追加 F1→H1,H1→F2,F2→H2,...
Next i
oDict(arrRelativeRef(nUBound)) = arrRelativeRef(0) ' 辞書に追加 BC2→(次のブロックの)F1
End If
' ' 値変更されたセルの行位置を取得して偶数に丸める(10→10,11→10,11→11,12→11,...)
nLevelRow = Target.Row And Not 1 ' 各ブロック毎の相対参照基準行位置
' ' 値変更されたセルの'基準行位置'分上のセルのアドレスを相対参照として取得
sRelativeRefPrev = Target.Offset(1 - nLevelRow).Address(0, 0)
' ' 値変更されたセルの相対参照アドレスが辞書に登録されていなければ処理を抜ける
If Not oDict.Exists(sRelativeRefPrev) Then Exit Sub
' ' 辞書を参照して、
' ' 値変更されたセルの相対参照アドレス に対応した
' ' 次に選択するべき相対参照セルアドレス を取得
sRelativeRefNext = oDict(sRelativeRefPrev)
' ' 次に選択するべき相対参照セルアドレスが"F1"に一致したならば、
' ' 基準行位置を次のブロックの基準行位置(2行下)に変更する
If sRelativeRefNext = sRelativeRefOrg Then nLevelRow = nLevelRow + 2
Application.EnableEvents = False ' Worksheet_SelectionChangeイベントを発生させないように抑止
' ' 'A列基準行セル' からみて
' ' 次に選択するべき相対参照セルアドレス の位置にあるセルを選択する
Cells(nLevelRow, "A").Range(sRelativeRefNext).Select
Application.EnableEvents = True ' イベント再開
End Sub
お早うございます。
朝早くからありがとうございます。
今日は休みなので、眺めてみます。
こころ遣い嬉です。またいつかここで、お会いしましょう。
No.2
- 回答日時:
#1です。
自己レスです。誤って、動作確認していたものとは違う版を掲げてしまいました。
すみませんが、差し替えをお願いします。失礼しました。
Option Explicit
Const SREF = "F1,H1,F2,H2,O1,Q1,O2,Q2,X1,Z1,X2,Z2,AG1,AI1,AG2,AI2,AP1,AR1,AP2,AR2,AZ1,BC1,AZ2,BC2"
Private oDict As Object ' Scripting.Dictionary
Private Sub Worksheet_Change(ByVal Target As Range)
Dim s As String
Dim nRow As Long
Dim n As Long
If Target.Count > 1 Then Exit Sub
If Target.Row < 10 Then Exit Sub
If Intersect(Target, Range(SREF).EntireColumn) Is Nothing Then Exit Sub
nRow = Target.Row And Not 1 ' 偶数に丸める 相対参照の基点となる行
s = Target.Offset(1 - nRow).Address(0, 0) ' 相対参照での参照文字列
On Error GoTo CrDict_
If Not oDict.Exists(s) Then Exit Sub ' 相対参照での参照文字列が定義した範囲でなければ抜け
On Error GoTo 0
n = oDict(s)
If n = 1 Then nRow = nRow + 2 ' 2行単位の右下端セルの場合、2行スキップ
Application.EnableEvents = False
On Error Resume Next
Cells(nRow, "A").Range(SREF).Areas(n).Select ' 相対参照
On Error GoTo 0
Application.EnableEvents = True
Exit Sub
CrDict_:
Dim v
Dim arr
Dim i As Long
Set oDict = CreateObject("Scripting.Dictionary")
arr = Split(SREF, ",")
i = 1
For Each v In arr
i = i + 1
oDict(v) = i
Next
oDict(arr(UBound(arr))) = 1
Resume
End Sub
見事なアドバイスありがとうございます。
ストレス無く動きます。素晴らしいです。
自分なりに理解に努力しましたが、難しいので理解できませんでした。
でも、少しずつ出来るよう続けていこうと思います。
ありがとうございました。m(__)m
No.1
- 回答日時:
こんにちは。
対象シートの【シートモジュールの先頭】に
下の記述を貼り付けてください。
Worksheet_Change イベントですので、
セルが入力モードになった後に確定したタイミングで動きます。
ただEnterキーを押しただけでは、機能しませんのでご注意を。
ただ順番に、というだけでなく、どこから始めても
定義してある次のセルを選択するように書いてあります。
簡単ではありますが一応、動作は確認しています。
法則性みたいのがあるのだとすると、
> ,AZ10,BC10,AZ11,BC11
は、これだけが特異なので、
,AY10,BA10,AY11,BA11
なのかな?と思ったりしますが、念の為そちらで、確認の上、
必要なら、下記の ,AZ1,BC1,AZ2,BC2 の部分を修正してください。
説明した方がいいのでしょうけれど、厚量過ぎて難しいと思って、
とりあえず、何も書いてません。
疑問や、不足があった場合にはお応えしますので、補足欄にでも書いて下さい。
Option Explicit
Const SREF = "F1,H1,F2,H2,O1,Q1,O2,Q2,X1,Z1,X2,Z2,AG1,AI1,AG2,AI2,AP1,AR1,AP2,AR2,AZ1,BC1,AZ2,BC2"
Private oDict As Object ' Scripting.Dictionary
Private Sub Worksheet_Change(ByVal Target As Range)
Dim s As String
Dim nRow As Long
Dim n As Long
If Target.Count > 1 Then Exit Sub
If Target.Row < 10 Then Exit Sub
If Intersect(Target, Range(SREF).EntireColumn) Is Nothing Then Exit Sub
nRow = Target.Row And Not 1 ' 偶数に丸める
s = Target.Offset(1 - nRow).Address(0, 0)
On Error GoTo CrDict_
If oDict.Exists(s) Then
On Error GoTo 0
n = oDict(s)
If n = 1 Then nRow = nRow + 2
Application.EnableEvents = False
On Error Resume Next
Cells(nRow, "A").Range(SREF).Areas(n).Select
On Error GoTo 0
Application.EnableEvents = True
End If
Exit Sub
CrDict_:
Dim v
Dim arr
Dim i As Long
Set oDict = CreateObject("Scripting.Dictionary")
arr = Split(SREF, ",")
i = 1
For Each v In arr
i = i + 1
oDict(v) = i
Next
oDict(arr(UBound(arr))) = 1
Resume
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 数学 「FFTの基本は、DFTはサンプル数Nが偶数なら 2つのDFTに分解できるということ。 分解するとD 3 2022/03/31 21:01
- 数学 数学の質問です。 kを正の実数とする。 点Pは△ABCの内部にあり、 kAP+5BP+3CP = 0 2 2023/07/03 21:24
- 飲み物・水・お茶 え!これ100%、ならば買おうかな。…しかし実際は… 10 2022/09/06 20:37
- 食べ物・食材 北本トマトカレー 1 2022/09/13 14:10
- その他(家族・家庭) 対話型AIは、家族・友人・恋人・配偶者に置き換われるような存在へとなっていくでしょうか。 1 2023/02/12 22:03
- 洋楽 ジャスティン・ビーバー夫妻、ニューヨークの高級レストランで入店拒否!? 1 2022/06/08 16:03
- 政治 立憲民主党が共産党と組んで、旧統一教会問題で自民党を徹底追求するぞと言った直後に辻元清美ちゃんが…… 4 2022/09/27 13:15
- FX・外国為替取引 円安・円高について 5 2023/01/04 11:20
- 宇宙科学・天文学・天気 日本初の月着陸船の件 2 2022/12/01 17:45
- 政治 「このクソッタレが!」名古屋の高級焼肉店個室で“人糞”放置事件が発生 3 2022/05/30 18:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA ユーザーフォーム ボタンク...
-
ExcelVBAを使って、値...
-
特定のセルが空白だったら、そ...
-
【Excel VBA】指定行以降をクリ...
-
Excel vbaで特定の文字以外が入...
-
i=cells(Rows.Count, 1)とi=cel...
-
Excelで指定した日付から過去の...
-
”戻り値”が変化したときに、マ...
-
Excelのプルダウンで2列分の情...
-
特定の文字を条件に行挿入とそ...
-
DataGridViewの各セル幅を自由...
-
EXCELで変数をペーストしたい
-
【VBA】カーソルのある行の1行...
-
【Excel】指定したセルの名前で...
-
連続する複数のセル値がすべて0...
-
VBAの計算で@が出てしまう件
-
Application.Matchで特定行の検索
-
Excelのハイパーリンクにマクロ...
-
VBAを使用した時間管理
-
DataGridViewのセル編集完了後...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ExcelVBAを使って、値...
-
特定のセルが空白だったら、そ...
-
【Excel VBA】指定行以降をクリ...
-
i=cells(Rows.Count, 1)とi=cel...
-
【Excel】指定したセルの名前で...
-
Excelで指定した日付から過去の...
-
特定の文字を条件に行挿入とそ...
-
Excel VBA、 別ブックの最終行...
-
EXCELで変数をペーストしたい
-
Excelのプルダウンで2列分の情...
-
Excel vbaで特定の文字以外が入...
-
TODAY()で設定したセルの日付...
-
screenupdatingが機能しなくて...
-
DataGridViewの各セル幅を自由...
-
Sub 要具ライフ() ActiveSheet....
-
【EXCEL VBA】Range("A:A").Fi...
-
VBAを使用した時間管理
-
VBAでセルをクリックする回...
-
セル色なしの行一括削除
-
エクセルVBAでコピーして順...
おすすめ情報
早速の連絡ありがとうございます。
勉強します。ちょっと待ってください。
早速の連絡ありがとうございます。
勉強します。ちょっと待ってください。