![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
私は、Excelの「マクロの記録」で自動記述されたマクロを少々いじる程度しかできないスキルです。
行いたい処理がEXCEL VBAで実現できなくて困っています。どうぞお力を貸してください。
毎日、添付した画像の「上の表」のようなデータが出ます。
「下の表」は、二日後のデータに見立てています。このように、日ごとに列が増えていく表です。
(値の部分は、数値で0か1しか入りません。)
(上下に表を並べていますが、実際には「月初から本日まで」の1つの表しかありません。)
ここで、やりたいことは・・・
最後の日付から遡って6日間にわたり1が連続したら、その行だけ取り出して別シートにコピーしたいのです。
添付画像には、「すべての6連続した1」に黄色の網掛けをしていますが、
必要なのは「一番最後の日から遡って6日連続しているものだけ」です。
たとえば7/10の時点(上の表)では、工藤さんの行だけが該当。
7/12時点(下の表)では、石井さんだけが該当することになります。
該当した行を丸ごと、別のシートにコピーしたいわけです。
日によって、該当する行が複数行存在するときもあります。
自分で考えた限りでは、
データの右端(合計列)を見つけ、そこから左へ1セルだけオフセット→変数へセット
そこからさらに左へ5セルオフセット→変数へセット
それを選択範囲の開始セルと終了セルにできれば、
その中身がすべて1だった場合のみ、その行をコピーすればよいのでは・・・
と考えました。
行を1ずつ下に移動しながら最終行まで処理を続ける。
それを、行が終わるまで、繰り返す・・・(日によって行は増えたり減ったりする)
(データは0か1かしか入らないので、最終日から6日間を範囲選択している場合、全部1か?という判断をしてもよいし、足して6か?という判断でもよさそうです)
しかし、オフセットでセルはセレクトできても、
それを開始セル・終了セルとした「範囲」にすることができず、
また、行が終わるまで繰り返す処理も記述の仕方がわかりませんでした。
全く形になっていないので書く意味はなさそうですが、自分の記述を下記に示します。
繰り返し処理はネットで検索しました。
----------------------
Sub testMacro()
'
' testMacro Macro
'
Dim i As Long
Dim MaxRow as Long
Range("A2").End(xlToRight).Select '2行目で、データの右端をセレクトする。変数にセットすべき?
Selection.Offset(0, -1).Select 'これが選択範囲の最初。変数にセットすべき?
Selection.Offset(0, -5).Select 'これが選択範囲の最後。変数にセットすべき?
Range(開始セル:終了セル).Select'この範囲指定がわからない
MaxRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row '最後の行を知る(どの列でもいい)
For i = 1 To MaxRow '1ずつ増やしながら最終行まで繰り返す
'範囲内が全部1かどうか(あるいは足して6かどうか)調べて、そうでなかったら次の行へ。
'もし全部1ならならコピーして別シートへコピー。
Next i
End Sub
----------------------
本当にまったく形になっていなくてすみません。
お力を貸していただけると嬉しいです
よろしくお願いします
![「1が6連続登場したらその行をコピーするV」の質問画像](http://oshiete.xgoo.jp/_/bucket/oshietegoo/images/media/1/514124572_5497c70da2b7b/M.jpg)
No.2ベストアンサー
- 回答日時:
No1のものです。
勉強のために解説するほどのものではないですが解説を書いてみました。
だいたい考え方はあっています。
実際の方法として要点ごとに以下のように解説致します。
不明な点があれば補足してください。
他サイト様ですが、
分かりやすい解説をされているサイトも参考でURLを載せておきます。
>該当した行を丸ごと、別のシートにコピーしたいわけです。
フォーマット(タイトル行や列幅等)を引き継ぐために
該当行をコピーではなく、シートをコピーしてから
ActiveSheet.Copy After:=ActiveSheet
Set mySt = ActiveSheet
不要行を削除する方法にしています。
Rows(i).Delete
>日によって、該当する行が複数行存在するときもあります。
全ての行に対して処理をしています。
行削除を行っているので若い行番号→最終行番号ですと
行削除した際に次の行番号が上にシフトしてしまい、
1個飛ばしになってしまうため、最終行から若い行(開始行)へ
Step値を-1として処理しています。
For i = .Range("A" & Rows.Count).End(xlUp).Row To 2 Step -1
~
Next i
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/v …
>データの右端(合計列)を見つけ、
>そこから左へ1セルだけオフセット→変数へセット
Findで「計」を検索し合計列の列番号を取得しています。
合計列の列番号から-1した値を最終日の列番号として利用します。
myCol = ActiveSheet.Rows(1).Find("計").Column - 1
http://www.moug.net/tech/exvba/0050116.html
>そこからさらに左へ5セルオフセット→変数へセット
>それを選択範囲の開始セルと終了セルにできれば、
セル範囲は『Range(開始セル,終了セル)』で指定できます。
.Range(.Cells(i, myCol - 5), .Cells(i, myCol))
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/v …
http://www.clayhouse.jp/vba/vba01.htm
>その中身がすべて1だった場合のみ、その行をコピー
>(あるいは足して6かどうか)
『WorksheetFunction.』+『関数名(引数)』で
エクセルのワークシート上で使用する関数を利用出来ます。
今回は『Sum』関数を使用し、引数に上記のセル範囲を設定しています。
Ifブロックで使用している『Not』は後に続く条件式が否定の場合に真となります。
よって、「対象範囲の合計値が6以外の場合に処理」となります。
If Not WorksheetFunction.Sum( _
.Range(.Cells(i, myCol - 5), .Cells(i, myCol)) _
) = 6 Then
~
End If
http://www.excel-vba.net/excel-condition-001.html
http://home.att.ne.jp/zeta/gen/excel/c04p20.htm
回答ありがとうございます。
Findの活用や If Notをつかった条件判断と繰り返し、大変参考になります。
また、丁寧な解説も入れてくださり、初心者として大変助かります!(^^)!
実はこの質問、作りたい全体プログラムの、もっとも難しい1部分についてアドバイスをいただこうと思ってのもので、実際にはさらにいろいろな処理を続けていく必要があります。
(なんだか、全部を丸投げするのって反則のような気がしまして・・・)
今回の回答をいただけて、びっくりするほどVBA構築のめどが立ってきました!!(^^)/
まだまだ難関はありますけれど~(´・ω・`)
↓↓↓ 完成目標は…こうです! ↓↓↓
今回の元データはチーム1.xlsブックのデータである。
ほかにもチーム2.xls、チーム3.xlsなど、10ファイルほどある。
既存の「連続6個.xls」というブックがあり、プログラムはその標準モジュールに記述する
連続6個.xlsは、チーム1.xlsを開いて、今回教えていただいたプログラムを実行する。
出力シートに抽出された6連続1のデータ行は、「連続6個.xls」の最終行にコピーされる。
この時、A列に入っていた人の名前を、ブック名と同じチーム1にする。(複数行あっても。)
続いてチーム2.xlsを開き、同処理実行。抽出されたデータは、「連続6個.xls」の最終行にさらにコピーされていく。A列はチーム2とする。
(出力シートに抽出された時点で、A列の全セルにブック名を入れておくべきですね♪
この時、書いて下さった処理構文
.Range(.Cells(i, myCol - 5), .Cells(i, myCol))
に近いものが使えそうです♪)
連続6個.xlsブックは、
チーム1 1 0 1 1 1 1 1 1 1 1
チーム1 1 0 1 0 1 1 1 1 1 1
チーム1 1 0 1 1 1 1 1 1 1 1
チーム2 0 0 0 0 1 1 1 1 1 1
チーム3 1 1 1 0 1 1 1 1 1 1
......
みたいな感じになるでしょう。
チーム1、チーム2、チーム3・・・という風に複数ブックを開いては処理して閉じる、をしていくので、
変数にブック名を配列としてチーム1、チーム2、チーム3…という風に入れて、
forで繰り返す時にブック名が入れ替わるようにできたらいいですよね♪
これもかなりの難関っぽいですねー ( ;∀;)
でもたぶん、これも教えていただいた
With ~ End With のところを活かしつつ、工夫する感じでしょうか~( *´艸`)
↑↑↑ 完成目標は…こうです! ↑↑↑
目標はこんな感じです♪前途多難ですネ(笑)
でも、本当に今回教えていただいた構文からの発展が見込めます。
大変うれしいです。(^^♪
もし、またどこかで躓いたら、似たような質問を載せると思います。
その時はまたぜひ、ご協力よろしくお願いします!!!(笑)
頑張ります、ありがとうございました! m(__)m
No.3
- 回答日時:
各ブックから条件一致を別ブックへ集約するという事でしたら、
シートコピー → 不要行削除では扱いにくいですね。
新規シート作成 → 条件一致行をコピーに変更しました。
以下の変更点となります。
(コード内の関連する箇所に該当番号をコメントしています)
(1)出力先の行数をカウントするcnt変数を追加
(2)6連続行の判定箇所で「Not」を削除
(3)ループ処理を最後から手前ではなく、開始から終了へ順送りに変更
(4)取得元と出力先のシートを配列変数(シートオブジェクト)に格納して処理
※)
補足の内容については質問の追加となり利用規約違反になりかねないため
この場での回答は控えさせていただきます。
不明な点があれば別途質問としてあげてください。
試行錯誤しながら、完成まで頑張ってください。
■変更VBAコード
Sub 判定コピー2()
'変数型宣言
Dim myCol As Long
Dim mySt(1) As Worksheet '(4)
Dim i As Long
Dim cnt As Long '(1)
'最終日取得
'(1行目の"計"を検索し、見つかった列-1を最終日の列番号とする)
myCol = ActiveSheet.Rows(1).Find("計").Column - 1
'コピー元シートを記憶 '(4)
Set mySt(0) = ActiveSheet
'シート新規作成 '(4)
'(コピー先のシートを作成)
Worksheets.Add After:=ActiveSheet
Set mySt(1) = ActiveSheet
'シート名設定
'(新規作成したコピー先のシート名を設定)
mySt(1).Name = "出力"
'行数分処理
With mySt(0)
For i = 2 To .Range("A" & Rows.Count).End(xlUp).Row '(3)
If WorksheetFunction.Sum(.Range(.Cells(i, myCol - 5), .Cells(i, myCol))) = 6 Then '(2)
'最終日手前6セル分の合計が6以外であれば行コピー
cnt = cnt + 1 '(1)
.Rows(i).Copy mySt(1).Rows(cnt)
End If
Next i
End With
End Sub
ありがとうございます~~(^з^)-☆
まさか変更版を書いていただけるとは思っていませんでした!(*^^*)
これでいよいよ完成に近づける気がします。
各処理の仕組みや意味が良く理解できましたので、今後にも役立てられる気がします。
どうもありがとうございました~~(*^^*)
もしこれに関する別の質問を目にされたときは、またぜひ助けていただきたいです(笑)
がんばります(*^^*)
No.1
- 回答日時:
シートを右クリック→コードの表示
または、Alt+F11でVBEを開き、標準モジュールを作成
してから最下のVBAコードを貼り付けてください。
コピー元のシートを表示した状態で、
表示→マクロ(または、Alt+F8)より「判定コピー」を選び「実行」してください。
表示中のシートの右側に「出力」という名前で新規シートが作成され、
該当の結果が表示されます。
注)
最終日の取得に『1行目』に存在する『「計」が入力されたセル』
の1つ手前の列を最終日の列として取得していますので、
「計」が見つからない場合はエラーとなります。
■VBAコード
Option Explicit
Sub 判定コピー()
'変数型宣言
Dim myCol As Long
Dim mySt As Worksheet
Dim i As Long
'最終日取得
'(1行目の"計"を検索し、見つかった列-1を最終日の列番号とする)
myCol = ActiveSheet.Rows(1).Find("計").Column - 1
'シート新規作成
'(コピー先のシートを作成)
ActiveSheet.Copy After:=ActiveSheet
Set mySt = ActiveSheet
'シート名設定
'(新規作成したコピー先のシート名を設定)
mySt.Name = "出力"
'行数分処理
With mySt
For i = .Range("A" & Rows.Count).End(xlUp).Row To 2 Step -1
If Not WorksheetFunction.Sum(.Range(.Cells(i, myCol - 5), .Cells(i, myCol))) = 6 Then
'最終日手前6セル分の合計が6以外であれば行削除
.Rows(i).Delete
End If
Next i
End With
End Sub
回答ありがとうございます~~~(^^)/
美しいプログラムですね!!
.Range(.Cells(i, myCol - 5), .Cells(i, myCol)))
のところとか、初心者がネットで解説を見た程度ではなかなか構成できないところですね~~
大変助かります。ありがとうございます(^_-)-☆
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 日付で矢印マクロ 4 2023/07/25 16:47
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) VBA 特定の列に入っているテキストをコピペ 2 2023/06/14 11:24
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Visual Basic(VBA) 最終行の指定について教えてください。 複数シートを1シートへまとめる下記マクロでは各シートの6行目を 1 2022/10/04 18:37
- Visual Basic(VBA) データのある範囲を選択するVBAについて 2 2022/09/03 00:20
- Excel(エクセル) エクセルのマクロでコピー後の貼り付け先を毎回指定したところにしたい 5 2022/08/12 10:47
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- Visual Basic(VBA) コード名シートA列と集計シートA列のコードが一致したら、コード名シートA5からk12の範囲をコピーし 1 2022/08/29 23:46
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ゴルフコンペの会費に係る消費...
-
会社が定期券を購入するなとい...
-
ユニットハウスの耐用年数と勘...
-
タイミーでバイトを雇った際の...
-
【至急】経理関係分かる方教え...
-
日商簿記以外のパソコンを利用...
-
【債務超過とは何か?】どうい...
-
キャリアに関するご相談です。 ...
-
吹き出しイラストの無料ダウン...
-
早めの回答をお願いします。 福...
-
建設業、工事台帳について。
-
ウーバーイーツで税金額をする...
-
今、パートで経理事務をしてい...
-
割り勘の一円未満の処理どうし...
-
法人です。経費にならないもの...
-
簿記三級の修正記入について 初...
-
税務調査
-
我が社の交通費申請について ア...
-
役員だけの社員旅行は経費にな...
-
有利子負債比率400%以上の企業...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excel2010の並べ替えで行の高さ...
-
リース初心者です 利子率の計...
-
エクセルで複数の勤務時間ごと...
-
エクセル関数で {=TABLE(,セル...
-
プルダウンで選択すると隣のセ...
-
エクセルで離れたセルを離れた...
-
60進法で複数セルの足し算、引...
-
エクセルで作った書類に、パン...
-
VBA 条件が一致した場合の...
-
Excelハイパーリンクのアドレス...
-
エクセルデータをワードへ反映...
-
至急! Excelで歩合計算
-
Excelのオートカルクの結果をコ...
-
今日の日付が第n曜日かを求める
-
エクセルの行高さが、挿入作業...
-
Excelの空白行を上に詰めるVBA...
-
エクセル フォームボタンクリ...
-
エクセルで一番下の日付や時刻...
-
EXCELでR1C1参照形式の絶対参照...
-
エクセルデータを拡大/縮小して...
おすすめ情報