『チェックを入れた情報を別のエクセルシートへ反映』(ANN) フォームコントロールのマクロでチェックボックスをC2から850個(行)作りました。 チェックボックスにチェックが入ったものは右横のD2にTRUEとして反映 チェックボックスにチェックが入っていないものはデフォルトのFALSEと反映されています。 同じエクセルでは作業が重たくなってしまうのでC2に配置しているチェックボックスにチェックをいれ、D2にTRUEと反映があったものをB2の情報のみ別のエクセルシートへ上から自動転機させていきたいのですが、良い方法をご教示いただけませんか? イメージ↓ □はチェックボックスです。 (マクロエクセル)   A         B       C    D 1 【タイトル行】 2管理番号/ここを別エクセルへ自動転記/ □ / TRUE (転記用別エクセル)   A         1 【タイトル行】 2転記されたBの情報 < 使用 Excel:Excel2010、使用 OS:Windows10 > ---- ワークシート上にチェックボックスを並べたのですね。 チェックを入れた段階で転記してほしいのですか? 何かボタン等を用意して一括で処理してほしいのですか? ボタンを用意する場合、それはVBAで行うということでよろしいですか? (わをん) 2018/02/01(木) 14:19 ---- (マクロエクセル)、(転記用別エクセル)っていうのはシート名ですかね。 とりあえずVBAつかうなら、 1.オートフィルタを実行してD列が、「True」になっているものを抽出する 2.Intersectで、「マクロエクセル」シートの「抽出した表」と「B列」が重なる範囲を抜き出して 3.COPYメソッドでコピー 、引数に 「転記用エクセル」シートの「A1」セルを指定 でどうですか? わをんさんの指摘部分も気になりますが・・・・ (上記の処理は逐一じゃなくて、一気にやるパターンです) (もこな2) 2018/02/01(木) 14:23 ---- わをんさん、もこなさん>チェックを入れた段階で転記してほしいのですか?はいそうです。 条件にあうだけなら転記用別エクセルに関数をいれて一括で転記すればいいのですが、 A B C 1 2 あ ■ TRUE 3 い □ FALSE 4 う □ FALSE 5 え ■ TRUE 6 お □ FALSE ↑これを 別のエクセルファイルに↓空白なしで随時コピー転記する方法が知りたいです。 A B C D 1 2 あ 3 え 4 5 6 VBAでも関数でも構わないのですが、私のPCのスペックがひくくて動作が重たくなりがちなのでできるだけ軽い処理を教えていただきたいです。 説明不足ですみません。。 (ANN) 2018/02/01(木) 14:46 ---- チェックを入れた段階で転記できたとして 後から、間違いに気づいて、チェックを外した場合は? (マナ) 2018/02/01(木) 21:40 ---- こんばんは! 今はコードがちょっと書けないですけど、 そのシートのチェンジイベントに 上から順番にみてtrueだったら転記 でいいんじゃないんですか? 配列数式の公式みたいな例の上から詰めるあの式でも いい様な? bookを開く開かないは別として 値だけなら右辺と左辺を=で結べばいいです なんか中途半端な回答で申し訳ないですけど なんとかなりますでしょうか? また、考え方はこんな感じでいいでしょうか? (SoulMan) 2018/02/01(木) 22:11 ---- マナさん>たしかに、するどいご指摘ありがとうございます。 あー、悩ましいです。 SoulManさん>そうですよね!考え方ありがとうございます。 本来であればループで式を作って。のほうがいいのかなとか思ったのですが、なかなかうまくいかず・・・ マクロを設定したエクセルに関数で振り分けして、=で結ぶのが作業が軽そうですよね。 転記元エクセルの動作が不安ですが・・・・・。 もしもっと良い式あれば教えてください。 よろしくお願いいたします。 (ANN) 2018/02/02(金) 09:46 ---- SoulManさんの仰ってる、チェンジイベントってワークシートのイベントを仰ってるのだとおもうんですけど、 自分もつかえるかな〜とおもって↓のコード書いて、テストしてみたんですが Private Sub Worksheet_Change(ByVal Target As Range) MsgBox (Target.Address) End Sub Msgbox発動しなかったです。Excel君からみれば、セルの値変えてるわけじゃないから検知しないんですかね・・・あっテスト環境は(Excel2013/win7)です (もこな2) 2018/02/02(金) 10:51 ---- ユーザーフォームで特定のコントロールを一括処理する要領で 全部のチェックボックスの状態を見て、Trueになったら横の情報を転記みたいなことができないかな? と思ってあちこち調べたりあがいたりしてみたんですけどなかなか進展しませんでした……。 簡単そうに見えて結構難しいですね、これ。 ちなみに、チェックボックスはActiveXコントロールでよかったでしょうか? (わをん) 2018/02/02(金) 13:30 ---- 最初に「フォームコントロールの…」とありますので、こっちでしょうね。 コントロールの書式設定に「リンクするセル」という項目があり、これを指定すると、チェック1つがセル1つに対応するようになります。こうしておけば、どの行のチェックなのかマクロで判断できるようになります(Worksheet_Changeも使えるようになります)。チェックボックスはセルに縛られないオブジェクトなので、こうでもしないと区別付かないのでは? そして、チェックする度に追加ではなく、一通りチェックON/OFFした後に、ボタンでも押すと、ONなものだけ追加するようなマクロにするのが自然かと思いますよ。 (???) 2018/02/02(金) 13:54 ---- あれ、、フォームコントロールのチェックボックス設置して、セルにリンクさせて、リンク先のセルにTrue,Falseが入る(切り替わる)状態で、Worksheet_Changeつかってみたんですけど、イベント拾えなかったんですが。いけます? 私のテスト変だったのかな・・・・ Worksheet_Changeは数式の結果が変わるみたいに、値が書き換えられないものはスルーされるから、リンクは数式の一種としてあつかってるのかな〜とおもったんですけど。 (もこな2) 2018/02/02(金) 14:12 ---- 私も今Excel2010で試してみたんですけど、Worksheet_Chenge動かないみたいで……? まあでも、やっぱり???さんご提案のように、とりあえず最初に転記したい情報を区別して 後で一括処理のほうがいいと思いますよ。 コードの書き方なんかも簡単になると思いますし、重いから必要なデータを別ファイルにしたい、 というならなおさら。 ちょっとだけ考えてみてくださいな。 (わをん) 2018/02/02(金) 14:43 ---- VBAでやるなら、記録(記憶?)用のシートを非表示状態でもっておいて、ブックのopenイベントで、こっそり現在値をもっておいて、チェックボタン操作するたびに、Worksheet.Calculateが発生するだろうから、そっちで、変更前と変更後を比較やることは出来そうなんですが、肝心の操作したフォームコントロールが何行目のものなのか取得する方法がわからない・・・とりあえず、 Private Sub Worksheet_Calculate()  「転記用別エクセル」シートをクリア  For 2行目から最終行まで   IF D列が、「True」だったら _    B列の値を「転記用エクセル」シートのA列、最終行+1へコピー  Next end sub ってかんじで、毎回全部を処理し直す方法ならいけそうですね。 また、いくつかの条件(作業列つかうとか、管理番号の重複不可とか)はあるけど、RANK関数でもできそう。 <↑こちらはちょっと調整中なので次投稿へ> (もこな2) 2018/02/02(金) 15:35 ---- 関数の場合 「マクロエクセル」シートのE、Fを作業列として使用。 (1)E2セルに「=IF(D2,A2,"")」と入力して、下に必要だけコピー(フィル) (2)F2セルに「=IF(E2="","",RANK(E2,E:E,1))」と入力して必要なだけコピー(フィル) 「転記用別エクセル」シートのB、Cを作業列として使用 (3)B2セルに「1」と入力して必要なだけ下にフィルして連番を作成。 (4)C2セルに「=MATCH(B2,転記用別エクセル!F:F,0)」と入力して必要なだけ下にコピー (5)A2セルに=IFERROR(INDEX(転記用別エクセル!B:B,MATCH(B2,転記用別エクセル!F:F,0),1),"") でいけるはず。 (もこな2) 2018/02/02(金) 16:10 ---- ほんとですね。もこな2さんの言うとおり、「リンクするセル」を設定したセルが変わっても、Changeイベントが発生しませんね。失礼しました。 そうなると、チェックの度に動作させるには、「マクロの登録」を使わないとですね。どのチェックボックスでも1つのマクロにしておいて、Application.Caller でどれを操作されたか調べる事ができます。 そこで例えば、ActiveSheet.CheckBoxes(Application.Caller).TopLeftCell.Row を調べれば、何行目のセルかが判るでしょう。 まぁ、OFF時動作も考えると、ボタン押下時に処理するのがお薦めですが。 (???) 2018/02/02(金) 16:22 ---- Application.Callerって初めて知ったんですけどすごいですねこれ……! Select Caseのコントロール版みたいな感じでとても便利。いいものを知ることができました。 OFF時はどうするのか気になるところですけど……。 後は質問者さんのお悩みが解決することを祈って傍観することにします。がんばってください。 (わをん) 2018/02/02(金) 16:57 ---- そういえば、Application.Callerという手がありましたね。 最近こっち↓で、紹介されてたのに思いつけず・・・残念(>_<) http://vbae.odyssey-com.co.jp/column4/s41402.html とりあえず、技術普及でリンクおいておきます。 (もこな2) 2018/02/02(金) 17:23 ---- こんばんは! なんか盛り上がってますねぇ汗 ほんとですね チェンジイベット感知しませんね汗 昨日寝ながらチェックの度にBookを開いても忙しいし、なんかややこしいなぁと思ってました。 どうしようかなぁと考えていたんですけど、ダブルクリックぐらいが一番現実的かなと汗 ということでダブルクリックで書いてみました。 後、Bookも開いているのが条件です。 開く開かないは別でトピを立てて頂くとして初歩的にはこんな感じでどうでしょう? Option Explicit Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Dim MyA As Variant Dim MyArry() As Variant Dim wb As Workbook Dim MyBook As Workbook Dim MyFlg As Boolean Dim i As Long Dim k As Long Cancel = True '転記用別エクセル.xlsx が開いているか調べて For Each wb In Workbooks If wb.Name = "転記用別エクセル.xlsx" Then MyFlg = True Set MyBook = wb End If Next If MyFlg = False Then MsgBox "転記用別エクセル を開いてから実行してください" Exit Sub End If '開いていたらデータをMyAに取得 MyA = Me.Range("A1").CurrentRegion.Value k = 1 ReDim MyArry(1 To UBound(MyA, 2), 1 To k) For i = LBound(MyA, 1) To UBound(MyA, 1) 'リンクセルが TRUE だったら If StrConv(MyA(i, 3), 1) = "TRUE" Then MyArry(1, k) = MyA(i, 1) k = k + 1 ReDim Preserve MyArry(1 To UBound(MyA, 2), 1 To k) End If Next With MyBook.Sheets("Sheet1") .Cells.Clear .Range("A1").Resize(UBound(MyArry, 2), 1).Value = Application.Transpose(MyArry) End With Set MyBook = Nothing Erase MyA, MyArry End Sub (SoulMan) 2018/02/02(金) 20:13 ---- それから配列の公式みたいな式ですけど一応 チェックボックスというBook名で試してみました。 Book名とかは適当に応用してください。 =IF(SUM(([チェックボックス.xlsm]Sheet1!$C$1:$C$5=TRUE)*1)