応用が効かなくて申し訳ありません。
1798323で素敵なご回答をいただいたのですが、
状況が進展して変わってくるとVBAの書き換えがわからなくなりました。もう一度教えてください。
※変更点は、入力元がAI列、『入力先をQ~V列に限定』したい点です。
Q R S T U V・・ AI
1 田中 鈴木 佐藤 山田
2 鈴木 山田 海岡
3 田中 佐藤 佐藤
というような表があり、T1に「山田」、S2「海岡」と、その行に関してAI列に新規の名前が入力されたときに自動入力することをVBAでどのように書けばよいのか、ご教授お願いいたします。
尚、3行目には「佐藤」さんがすでいるので入力不要です。
よろしくお願いします。
No.1
- 回答日時:
こんにちは。
こんなものでよいと思います。
イベント・ドリブン型のマクロですから、使い方は、単に、AI列に入力するだけです。
'シートタブから、コードの表示で以下を貼り付けます。
'---------------------------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
With Target
'35列 =AI列
If .Column <> 35 Then Exit Sub
If .Count > 1 Then Exit Sub '複数のセルの場合のEnter除外
'17 =Q列より前か 22= V列より後は除外
If (.End(xlToLeft).Column < 17 Or .End(xlToLeft).Column >= 22) Then Exit Sub
If .End(xlToLeft).Value <> .Value Then
Application.EnableEvents = False
.End(xlToLeft).Offset(, 1).Value = .Value
Application.EnableEvents = True
End If
End With
End Sub
'---------------------------------------------------
.
この回答への補足
Wendy02さん、こんにちは。いつもありがとうございます。
以前にもご指導いただきました。
シートタプを右クリックしてコード表示で貼りつけてみました。
1行目で試してみると、うまくいきましたが、2行目以下がなかうまくできませんでした。私の理解不足の為だとは思います。尚、引き続きご指導お願いいたします。よろしくお願いいたします。
No.2
- 回答日時:
kamejiroさんの応用ということなら
それぞれの入力位置を検討といううことになるかと
Sub テスト2()
i = 1
Do Until Cells(i, 35) = ""
j = 17
flg = ""
Do Until flg = "END"
If j = 22 Then
flg = "END"
End If
If Cells(i, j) = Cells(i, 35) Then
flg = "END"
End If
If Cells(i, j) = "" Then
Cells(i, j) = Cells(i, 35)
flg = "END"
End If
j = j + 1
Loop
i = i + 1
Loop
End Sub
それにしてもkamejiroさん、最初からこのような変更もありうるとを想定してのコードなのかすばらしいな~ ('-'*)
VBA勉強中の onntaoでした
この回答への補足
ありがとうございます^^。できました。
しかしながら、1行目に見出し、2行目からデータ入力というケースなら可能なようですが、
今回設定しているシートは、1行目~4行目に見出しや空白にあけておきたいのです。5行目から入力したい場合、このマクロを実行したときにうまくいかないみたいです。引き続きご指導いただけますでしょうか?
onntaoさん、ありがとうございました。大変参考になりました。入力元の1行目~4行目に何か文字がはいっておれば、5行目からの入力が可能であることは確認できました。kamejiroさんからもご回答いただいて尚、補足質問をお願いしています。ご回答、心より感謝いたします。当初ポイント対象だったのですが、その後、多数の方のご回答をいただいた関係で、今回はごめんなさい。m(_ _)m
No.3
- 回答日時:
こんにちは~
Q列からV列がすべてうまっている状態で、AI列に別の名前を入力した場合はどうするのでしょうか?
それは考慮しなくてもよければ、以下のコードを試してみてください。
該当シートのシート見出しを右クリックして 「コードの表示」
'------------------------------------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
With Target
If .Column <> 35 Or .Row < 5 Then Exit Sub
If .Count > 1 Then Exit Sub
If .Value = "" Then Exit Sub
Application.EnableEvents = False
For i = 17 To 22
If Cells(.Row, i).Value = .Value Then
Exit For
Else
If Cells(.Row, i).Value = "" Then
Cells(.Row, i).Value = .Value
Exit For
End If
End If
Next i
Application.EnableEvents = True
End With
End Sub
'-----------------------------------------------------------
No.1さんのだと、Q列からV列に何も入力されていないような場合うまくいかないと思います。
あと、重複チェックもちょっとちがうような‥
かんちがいでしたらゴメンナサイ。
この回答への補足
shiotan99さん、ありがとうございました。完璧です。
Q~Vの6件を越えることはないと仕事で使う現場からの要望でしたが、増やしたいとき、たとえば、z列まで拡張したいときは、8行目の「For i = 17 To 22」をさわればいいのですね?
もうひとつ、追加質問事項をお世話いただけるでしょうか?入力元をAIだけでなく、ほかにもいくつか設定したいのです。たとえばAI,AQ,AY・・・といくつか入力元を持ちたいのです。入力先はQ~Vで変更ありません。よろしくご指導お願いいたします。楽しみにお待ち申し上げています。
No.4
- 回答日時:
#3さんへ
Wendy02です。こちらのコードを、念のため、Watch 式 を取って見ましたが、値は正しくとれているようですが・・・。
>No.1さんのだと、Q列からV列に何も入力されていないような場合うまくいかないと思います。
If (.End(xlToLeft).Column < 17 Or .End(xlToLeft).Column >= 22) Then Exit Sub
このように、除外条件を作っていますね。
つまり、35=AI列以下で、何も入っていない場合は、.End(xlToLeft).Column =1 になります。また、V列以降に入っている場合は、22 以上になりますから、除外されます。
>重複チェックもちょっとちがうような‥
End プロパティで、ActiveCell や Target(セル)が移動するわけではありません。論理的ワークシートのセルの上を走るだけです。SelectやActivate で初めて移動します。
' AI列以下の最も右の列の値 と AI列の値
If .End(xlToLeft).Value <> .Value Then
' 見つかった場所から、セル1つ左に、Target(AI列の値)を代入する
.End(xlToLeft).Offset(, 1).Value = .Value
ということです。
イベント・ドリブン型マクロの、ChangeやSelectionChangeイベントは、かなり重い部類に入りますから、なるべく簡易な方法で、そのプロシージャ内の停留時間を減らすのがよいと思います。WorksheetFunction を使った、他の手がないわけではないのですが、私としては、ご質問者のトラブルが、何が原因なのははっきりしませんが、この件はこのぐらいにしておきます。
Wendy02さん、いつもありがとうございます。質問に対する真摯な態度で取り組んでご回答くださることに感謝いたします。マクロ確認してみました。ありがとうございます。今回はポイントごめんなさい<(_ _)>
またご指導お願いいたします。
No.5
- 回答日時:
P列にはいつもデータがあるとします。
Q-W列について左に詰めて追加します。質問に対し、Y列にデータを入れることに変えてます。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 24 Then 'Y列について値変化
r = Target.Row
If Application.WorksheetFunction.CountIf(Range("Q" & r & ":W" & r), Target) = 0 Then
Range("w" & r).End(xlToLeft).Offset(0, 1) = Target
End If
End If
End Sub
短いことを趣旨にしてますが、普通には動きますが特殊ケースでは
ボロがでるかもしれません。
ご回答ありがとうございます。imogasiさんは、エクセルに関するご回答をいつもなさってますね^^実は私もそのご回答で勉強させていただいています。また、よろしくお願いします。(今回は、ポイントなくてごめんなさい<(_ _)>)
No.6
- 回答日時:
Wendy02です。
なぜ、違っているのか、理由がわからなかったので、もう一度、ご質問自体を読み直してみました。「AI列に新規の名前が入力されたときに自動入力すること」ということをキーワードにして考えてみました。
私は、「初めに、入力した文字ありき」という解釈でしたから。
もし、そういう条件だとしたら、以下のようなマクロでよいかと思います。
・特定の範囲に、文字があるなしに問わず、左詰で入力をしていく。
・特定の範囲に対して、重複を許さない
・特定の範囲を越えたら、入力させない。
まあ、これでダメなら、深追いしないほうがよいかもしれませんね。(^^;
以下は、ごちゃごちゃしているように見えるかもしれませんが、Visual Basic Editor に貼り付ければ見えます。
なお、これも、特定の範囲の中で、セルが空いている場合は、そこを左を優先に詰めます。なお、以下のコードは、かなりに特殊な部類のものになります。オーソドックスとは言えません。
'---------------------------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
Dim myCol As Integer
'==================================
'設定項目(入力開始+ 設定範囲)
Const IMPUT_ROW As Integer = 5 '行
Const IMPUT_COLUMN As Integer = 35 'AI列
'---------------------------------
Const LEFT_COLUMN As Integer = 17 '左列
Const RIGHT_COLUMN As Integer = 22 '右列
'==================================
With Target
If .Column <> IMPUT_COLUMN Or .Row < IMPUT_ROW Then Exit Sub
If .Count > 1 Then Exit Sub
On Error Resume Next
If WorksheetFunction.CountIf(Range(Cells(.Row, LEFT_COLUMN), Cells(.Row, RIGHT_COLUMN)), .Value) > 0 Then Exit Sub
If WorksheetFunction.CountBlank(Range(Cells(.Row, LEFT_COLUMN), Cells(.Row, RIGHT_COLUMN))) = 0 Then MsgBox "その範囲は、一杯です。", vbInformation: Exit Sub
myCol = Evaluate("MATCH(TRUE," & Range(Cells(.Row, LEFT_COLUMN), Cells(.Row, RIGHT_COLUMN)).Address & "="""",0)")
If Err.Number > 0 Then Exit Sub
On Error GoTo 0
Application.EnableEvents = False
Cells(.Row, LEFT_COLUMN + myCol - 1).Value = .Value
Application.EnableEvents = True
End With
End Sub
'---------------------------------------------------
.
たびたび失礼します。質問を読み直してまで再度ご返答いただき、あらためて心より感謝いたします。私の質問がわかりにくかったのですね。ごめなさい。
さっきのお礼もこちらの欄に書くべきでした。またの機会にもこれに懲りずにご指導ください。ありがとうございました。^^
No.7
- 回答日時:
kamejiroです。
入力元列と入力先列に自由度を持たせたいのであれば、
入力元列 何行目から何行目か
入力先列 何列目から何列目か
こちらを別のシート(例えば、Sheet2)に値を入れてこちらを参照しながら動作するようにしてみてはいかがでしょうか。
Sheet2を次のように入力しておきます。
(例1)
A B
1 入力元列番号 27 …AA列
2 入力元開始行 1
3 入力元終了行 10 …1行目から10行目
4 入力先開始列 1
5 入力先終了列 26 …A列からZ列
(例2)
A B
1 入力元列番号 35 …AI列
2 入力元開始行 1
3 入力元終了行 13 …1行目から13行目
4 入力先開始列 17
5 入力先終了列 22 …Q列からV列
VBAは、
Sub テスト()
i = Worksheets("Sheet2").Cells(2, 2)
Do Until i = Worksheets("Sheet2").Cells(3, 2)
j = Worksheets("Sheet2").Cells(4, 2)
flg = ""
Do Until flg = "END"
If j = Worksheets("Sheet2").Cells(5, 2) Then
flg = "END"
End If
If Cells(i, j) = Cells(i, Worksheets("Sheet2").Cells(1, 2)) Then
flg = "END"
End If
If Cells(i, j) = "" Then
Cells(i, j) = Cells(i, Worksheets("Sheet2").Cells(1, 2))
flg = "END"
End If
j = j + 1
Loop
i = i + 1
Loop
End Sub
と書き換えてみてはいかがでしょうか。
※継ぎ接ぎの即席VBAゆえ、見づらいかもしれませんが…。
この回答への補足
kamejiroさん、深夜のご回答を感謝いたします。私の理解不足だけなのかもしれませんが、質問をお許しください。《入力先は一定で、『入力元』を複数同時にもちたい》ケースでの書き方が尚、わかりません。もしよろしければご指導お願いします。例えば、入力元がAI,AQ,AY・・・、入力先は変わらずQ~Vといった具合です。よろしくお願いいたします。
補足日時:2005/11/25 10:56No.8
- 回答日時:
No.3です。
いつの間にかずいぶんにぎやかになっていますね。
> たとえば、z列まで拡張したいときは、
> 8行目の「For i = 17 To 22」をさわればいいのですね?
そうです。Z列の列番号は 26ですから
For i = 17 To 26
としてください。
> AI,AQ,AY・・・といくつか入力元を持ちたいのです。
AI列の列番号が 35ですから、
If .Column <> 35 Then Exit Sub
とすれば、AI列以外はここで処理を終了します。
AQ列、AY列も入力元にするなら、AND演算子でつなげてやってください。
列番号は、AQ列が 43、AY列が 51ですから、
If .Column <> 35 And .Column <> 43 And .Column <> 51 Then Exit Sub
となります。
または、
Select Case .Column
Case 35, 43, 51
Case Else
Exit Sub
End Select
としてもかまいません。入力元の列番号を
Case 35, 43, 51
のようにカンマをつけて列挙してください。
列番号がわからなければ、その列のどのセルでもいいので =COLUMN() と入力すればわかります。
整理すると、最初の部分は↓な感じです( AI列、AQ列、AY列が入力元の場合 )。
'-----------------------------------------
Dim i As Integer
With Target
'入力元
Select Case .Column
Case 35, 43, 51
Case Else
Exit Sub
End Select
If .Row < 5 Or .Count > 1 Then Exit Sub
If .Value = "" Then Exit Sub
'-----------------------------------------
◆
ついでに、No.3 をちょっと変更してみました( 入力元…AI列、AQ列、AY列です )。
↓の場合、入力先を拡張するときは、3行目の Const endCol As Integer = 22 の 22が V列の列番号ですから、これを修正してください。
'------------------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
'入力先(変更の場合↓を修正)
Const startCol As Integer = 17
Const endCol As Integer = 22
With Target
'入力元(変更の場合↓を修正)
Select Case .Column
Case 35, 43, 51
Case Else
Exit Sub
End Select
If .Row < 5 Or .Count > 1 Then Exit Sub
If .Value = "" Then Exit Sub
If WorksheetFunction.CountIf(Range(Cells(.Row, startCol), Cells(.Row, endCol)), "") = 0 Then Exit Sub
If WorksheetFunction.CountIf(Range(Cells(.Row, startCol), Cells(.Row, endCol)), .Value) > 0 Then Exit Sub
For i = startCol To endCol
If Cells(.Row, i).Value = "" Then
Application.EnableEvents = False
Cells(.Row, i).Value = .Value
Application.EnableEvents = True
Exit For
End If
Next i
End With
End Sub
'--------------------------------------------
この回答への補足
shiotan99さん、懇切丁寧なご回答、解説をありがとうございます。確認できました。ほぼ理想通りです。本当に感謝いたします。shiotan99さんのご回答を待ってよかったです^^
もう一点だけご質問をすることをお許しください。AI5に「田中」(誤)と入力(Entaer)して、あっ!間違えたということで「中田」(正)を入力しなおすと、入力先に「田中」残り、その次の列に「中田」が入ります。このようなケースで入力先の「田中」(誤)の上に「中田」(正)を上書きということまでは難しいでしょうか?
No.9
- 回答日時:
こんばんは。
Wendy02です。もう、余計な口出しになると思いますので、コードの公開は控えますが、ちょっと、関わったので、一応書いておきます。
>このようなケースで入力先の「田中」(誤)の上に「中田」(正)を上書きということまでは難しいでしょうか?
Static変数 にして、プロシージャの最後に、Targetのアドレスを確保すればよいのではありませんか? 後は、文字列の前に、プレフィックスでもつけて、例えば「!」などを付けて、通常入力とは分岐させて、修正用入力として、2文字目からを、前のセルに飛ばせば出来ますね。
----------------------------------
(Off Topic は削除される可能性があるのですが)
>今回はポイントごめんなさい
人によりけりだと思いますが、ポイントよりも、質問者さんの心のこもったお礼の一言のほうが大きいものなのです。点数は心には残りませんが、丁寧なお礼は心に残ります。次の回答の励みになります。
Wendy02さん、いつもありがとうございます。職場でしかネットがなくて御礼がおそくなり申し訳ありません。Wendy02さんのコメントの方こそ、私の心に潤いをいただきました。ありがとうございます。ご指導内容については、私が初心者であることからも今は理解できていませんが、がんばって勉強してみますね。今後もよろしくお願いします。
No.10
- 回答日時:
No.3 & No.8です。
> 入力先の「田中」(誤)の上に「中田」(正)を
> 上書きということまでは難しいでしょうか?
単に 「中田」 と入力しただけでは、フツーに入力したいのか上書きしたいのか判断できませんよね。
これは上書きだよ~、とわかるものが名前の前にでも入力されていればできると思います。
何か記号を入力すればいいのですが、特定の記号だと何を入力するのか覚えていられるかちょっと不安です。
★ で、名前の前に何でもいいので数字を入力すれば、これは上書きしてね、というサインだということにしてみました。
上書きしたい場合は、「1中田」 とか 「3中田」 というように入力する、ということです。( 一桁の数字です! )
↓な感じです( 直前に入力したものしか変更できません )。
'-----------------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
Dim ret As Integer
Dim myName As String
Dim myFlag As Boolean
Static myLastCell As String
Static myLastRow As Long
'入力先(変更の場合↓を修正)
Const startCol As Integer = 17
Const endCol As Integer = 22
With Target
'入力元(変更の場合↓を修正)
Select Case .Column
Case 35, 43, 51
Case Else
Exit Sub
End Select
If .Row < 5 Or .Count > 1 Then Exit Sub
If .Value = "" Then Exit Sub
'名前の前が数字?
myFlag = False
If Not IsNumeric(Left(.Value, 1)) Then
myName = .Value
Else
If Len(.Value) = 1 Then
MsgBox "数字のあとに変更したい名前を入力してください!", vbExclamation
Exit Sub
End If
If myLastCell = "" Then
MsgBox "前回入力情報がありませんので変更できません!", vbInformation
Exit Sub
End If
If myLastRow <> .Row Then
MsgBox "現在位置が、前回入力した行番号とちがうので変更できません!", vbExclamation
Exit Sub
End If
myFlag = True
myName = LTrim(Mid(.Value, 2))
End If
If WorksheetFunction.CountIf(Range(Cells(.Row, startCol), Cells(.Row, endCol)), myName) > 0 Then
MsgBox myName & "さんは入力済ですよ!", vbInformation
Exit Sub
End If
'名前上書き
If myFlag Then
ret = MsgBox("入力済の「" & Range(myLastCell).Value _
& "」さんを「" & myName & "」さんに変更します。" _
& vbNewLine & vbNewLine & "よろしいですか?", vbQuestion + vbOKCancel)
If ret = vbOK Then
Application.EnableEvents = False
Range(myLastCell).Value = myName
.Value = myName
Application.EnableEvents = True
End If
Exit Sub
End If
If WorksheetFunction.CountIf(Range(Cells(.Row, startCol), Cells(.Row, endCol)), "") = 0 Then
MsgBox "この行にはこれ以上入力できません!", vbInformation
Else
For i = startCol To endCol
If Cells(.Row, i).Value = "" Then
Application.EnableEvents = False
Cells(.Row, i).Value = .Value
Application.EnableEvents = True
myLastCell = Cells(.Row, i).Address
myLastRow = .Row
Exit For
End If
Next i
End If
End With
End Sub
'------------------------------------------
shiotan99さん、ありがとうございます。ネットが職場でしかつながっていなくって、御礼が遅くなって申し訳ありません。今から確認してみます。取りいそぎ心からの感謝をと思います。まさかできるとは!VBAはすばらしいものですね。それ以上にshiotan99さんの構築力、すばらしいです。確認後No.12のお礼欄で改めて御礼申し上げます。他業務で遅くなるかもしれませんが・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelマクロ 差分抽出の方法が知りたいです。 2 2023/03/07 13:25
- Excel(エクセル) EXCEL 関数を教えてください。(A列の同じ値が複数ある場合vlookupで出来ますか) 4 2022/12/07 20:54
- PHP PHPでCSVを出力するさいに、ループの中で前の行の値を変更したい 1 2022/10/27 14:21
- 計算機科学 Excel ある行と列が交わったところにマークを付けるには 7 2023/01/24 08:46
- Excel(エクセル) エクセルの条件付き書式 個人シートを参照して集計シートに色付けしたい 1 2023/06/22 00:39
- その他(IT・Webサービス) メニューについて 3 2022/07/12 16:06
- PHP MySql PHP 2つのテーブルをJOINで結合 user_idで抽出 1 2023/01/03 14:04
- Excel(エクセル) エクセルにて別シートの値を参照したif式で任意のセルと同じ値を結果に反映させたいです 3 2022/06/02 11:34
- PHP ファイルの書き込みについて教えて下さい。 1 2023/03/20 12:01
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
すべてのシートを選択してエク...
-
合計が0の行を削除
-
エクセルで時刻を自動入力する方法
-
Excelのデータが重いのはなぜで...
-
ローマ字入力で「トゥ」を入力...
-
【世界はデータで出来ている】...
-
「未使用」と「不使用」ってど...
-
Excelでエラー(#N/Aなど)値を...
-
1点の辻の字に変換したいがエク...
-
エクセルからアクセスにインポ...
-
SUM関数の範囲に#N/Aが...
-
「T」「H」「C」などだけが入力...
-
Eエクセルの計算方法で空欄を0...
-
自動改札のエラーって…
-
ExcelでVBAを使用した際に、『...
-
APEXをやっていたらこんなエラ...
-
もしセルが"#N/A"なら~をする...
-
エクセルで0.0と表示したい
-
VBAでユーザーフォームの表示を...
-
i-Padで、チルダ(~)を入力で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
すべてのシートを選択してエク...
-
エクセルで時刻を自動入力する方法
-
Excelのデータが重いのはなぜで...
-
Excel VBA 答えが0になってし...
-
EXCEL VBA 区切り位置のプログ...
-
エクセルマクロについて データ...
-
エクセル。ブック内検索で重複...
-
エクセルで30日以内に同内容の...
-
スプレッドシートで、指定した...
-
合計が0の行を削除
-
エクセルで隣のセルと同じ数字...
-
エクセルの中の漢字を一度にカ...
-
excel フレームのように一部...
-
エクセルで漢字がうまく並び替...
-
エクセルの入力 エンターキーで...
-
A列を検索し一致した行を表示。...
-
Excel2003での並べ替えについて
-
Excelユーザーフォームでのデー...
-
エクセルの既存のシートでは入...
-
エクセルで自動入力をマクロで...
おすすめ情報