• ベストアンサー

エクセルVBAでできますか?

以前ここでこんな質問をさせていただきました。 ________________________________________________ エクセルで台帳を作成するため、sheet1に次の通り情報を入力しました。    A  B    C     D 1 日付 名前  住所   申請事由   2 1/1 甲川  東京都    1 3 1/2 乙本  大阪府     1 4 1/2 丙藤  北海道    2 5 2/1 甲山  京都府     3 ・ ・  ・  ・        ・ そして、sheet2に申請事項1の人の情報を、sheet3に申請事項2の人の情報を、sheet4に申請事項3の人の情報を空白を開けずに次の通り詰めて入力したいのです。 sheet2(申請事由1の人)     A      B      C 1  日付  名前   住所 2  1/1 甲川  東京都 3   1/2 乙本  大阪府 4 ・   ・    ・ sheet3(申請事由2の人)     A      B      C 1  日付  名前   住所 2  1/2   丙藤  北海道 3 ・   ・    ・ 4 ・   ・    ・ sheet1に日付、名前等を入力しただけで、各事由事に他のsheetに詰めて入力されるよう関数式で入力することは可能かどうか教えてください。よろしくお願いします。 ______________________________________________ その際、関数でするやり方を教えてもらったのですが、(A3=IF(ROW(A1)>COUNTIF(Sheet1!$D$1:$D$100,$A$1),"",INDEX(Sheet1!A$1:A$100,SMALL(INDEX(SUBSTITUTE((Sheet1!$D$1:$D$100=$A$1)*1,0,10^5)*ROW($1:$100),),ROW(A1))))というやり方)何しろデータが10000件くらいあり、かなり処理速度が重いです。どなたかマクロで上記の処理の方法を教えていただけませんでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

こんなの簡単だよ。ただし経験が相当ないと、思いつくという方法ではないかもしれない。 別シートに書き出すコードを経験ないと出来ないが。 (1)Sheet1の最下行を知る(定石コードがある。これを知らなければこの課題レベルは無理) (2)最初データ行から終わりの行まで下記を繰り返す (3)D列で今の行のデータが   1-->Sheet2   2ーー>Sheet3   ・・・ のようにプログラムの中に対応テーブルを作って、書き出すシートの シート名を割り出す。 (4)割り出したシートの最終行を割り出し、その下にSheet1の今見てる行の、A,B,C列のデータを代入する。 ーー 何も難しいスキルを使わない。 Sub test02() d = Worksheets("Sheet1").Range("A65536").End(xlUp).Row 'Sheet1の最下行 ' MsgBox d st = Array("", "Sheet2", "sheet3", "Sheet3") '番号とシート名の対応テーブル For i = 1 To d '最下行まで繰り返し For x = 1 To 2 '事由の数だけ探す If Worksheets("Sheet1").Cells(i, "D") = x Then dt = Worksheets(st(x)).Cells(65536, "A").End(xlUp).Row '書き出しシーとの最下行 Worksheets(st(x)).Cells(dt + 1, "A") = Worksheets("Sheet1").Cells(i, "A") Worksheets(st(x)).Cells(dt + 1, "B") = Worksheets("Sheet1").Cells(i, "B") Worksheets(st(x)).Cells(dt + 1, "C") = Worksheets("Sheet1").Cells(i, "C") Else End If Next x Next i End Sub ーー 例データ Sheet1 日付  名前 住所    申請事由          a1 b1 c1 1 a2 b2 c2 2 a3 b3 c3 1 a4 b4 c4 1 a5 b5 c5 2 a6 b6 c6 2 a7 b7 c7 1 a8 b8 c8 1 a9 b9 c9 2 Sheet2 a1 b1 c1 a3 b3 c3 a4 b4 c4 a7 b7 c7 a8 b8 c8 Sheet3 略 再テストするときは、Sheet2,Sheet3以下はクリアして行うこと。 そうしないと下へ下へ積み重なる。

asahijp
質問者

お礼

回答いただきましてありがとうございます。imogasiさんにはいつもお世話になっております。教えてもらったとおりにやったら望むとおりにできました。ありがとうございました。

その他の回答 (3)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんばんは。 単に数式が重いだけなら、貼り付けた後に、コピーして値貼り付けしても、同じだと思いますが、マクロを作ってみました。なお、実際は、Sheet1 に CommandButton をつければよいと思います。 なお、申請事由のデータは、数値のみのほうがよいです。文字列の場合は、空白を処理するオプションが必要です。また、1,000程度の振り分けでしたら、もっと可能だと思いますが、シートは、当面、上限は、40枚程度だと思ってください。本来は、シート名が気になりますが、それは、そのままにしておきます。 シートを開くときは、ハイパーリンクを、Sheet1 につけると良いと思います。 Sub DataClassify() '-------------------------   'DataClassify   Dim r As Range   Dim shCnt As Variant   Dim mDataBase As Range   Dim CritDat As Variant   Dim i As Integer   Dim v As Variant      '臨時のクライテリアの出力のセル   '周辺にデータがないこと   Const Out As String = "AA1"      Application.ScreenUpdating = False   'シート名は変更してもよいですが、タブの位置が一番左端になくてはなりません。   With Worksheets("Sheet1")      Set mDataBase = .Range("A1").CurrentRegion     Set r = mDataBase.Columns(4)     'ユニークデータの出力     r.AdvancedFilter _     Action:=xlFilterCopy, _     CopyToRange:=Range(Out), _     Unique:=True          '申請事由のデータ取得     CritDat = .Range(.Range(Out).Offset(1), .Cells(65536, Range(Out).Column).End(xlUp)).Value          'シートの数の確認     shCnt = UBound(CritDat, 1) + 1     If shCnt > Worksheets.Count Then       Worksheets.Add After:=Worksheets(Worksheets.Count), Count:=shCnt - _       Worksheets.Count     End If     .Select     'シートの内容のチェック     For i = 2 To Worksheets.Count       With Worksheets(i)         '一括で消してよい場合は、*の行を消し         '.Cells.ClearContents だけ残す         If WorksheetFunction.CountA(.Cells) > 0 Then '*           If MsgBox(.Name & " は、空のシートではありませんが、データを削除してよろしいですか?", vbOKCancel) = vbOK Then '*             .Cells.ClearContents 'これだけ残す           Else '*             MsgBox "マクロを中止します", 64 '*             GoTo Quit '*           End If '*         End If '*       End With     Next i      'シート数の初期値     i = 1     'フィルタオプション     For Each v In CritDat       '数式の出力       .Range(Out).Offset(1, 1).FormulaLocal = "=D2=" & v       mDataBase _       .AdvancedFilter Action:=xlFilterCopy, _       CriteriaRange:=.Range(Out).Offset(, 1).Resize(2), _       CopyToRange:=Worksheets(i + 1).Range("A1"), _       Unique:=False       'ペーストした申請事由を消去       Worksheets(i + 1).Range("A1").CurrentRegion.Columns(4).ClearContents       i = i + 1     Next v Quit:     .Range(Out).CurrentRegion.ClearContents   End With   Application.ScreenUpdating = True   Set r = Nothing   Set mDataBase = Nothing End Sub

asahijp
質問者

お礼

回答どうもありがとうございます。マクロでも色々やり方があるみたいですね。教えてもらったやり方についても勉強してみたいと思います。どうもありがとうございました。

  • kuma3f
  • ベストアンサー率63% (28/44)
回答No.2

思われていることと違っていましたらすみませんが、Sheet1で入力後、マクロでフィルタを使って振り分けされてはどうでしょうか。 参考までに次のコードでマクロに貼り付けて試してみてください。 元を壊してはいけないので、コピーした台帳で試してみてください。 Altキー押しながらF8キーを押します。  ↓ マクロのダイアログが表示されたらマクロ名に自由に名前を入力してください。(例:振分)  ↓ 名前を入力しましたら、「作成」をクリック  ↓ Microsoft Visual Basicの画面が開きますのでSub 振分()の下に次のコードをコピーして貼り付けてください。 Application.ScreenUpdating = False Sheets("sheet2").Cells.ClearContents Sheets("sheet3").Cells.ClearContents Sheets("sheet4").Cells.ClearContents '*** 申請事由1→Sheet2 *** Sheets("Sheet1").Range("A1").Select Selection.AutoFilter Selection.AutoFilter Field:=4, Criteria1:="1" Cells.Select Selection.Copy Sheets("Sheet2").Select Sheets("Sheet2").Range("A1").Select ActiveSheet.Paste Range("A1").Select Sheets("Sheet1").Select Selection.AutoFilter '*** 申請事由2→Sheet3 *** Sheets("Sheet1").Range("A1").Select Selection.AutoFilter Selection.AutoFilter Field:=4, Criteria1:="2" Cells.Select Selection.Copy Sheets("Sheet3").Select Sheets("Sheet3").Range("A1").Select ActiveSheet.Paste Range("A1").Select Sheets("Sheet1").Select Selection.AutoFilter '*** 申請事由3→Sheet4 *** Sheets("Sheet1").Range("A1").Select Selection.AutoFilter Selection.AutoFilter Field:=4, Criteria1:="3" Cells.Select Selection.Copy Sheets("Sheet4").Select Sheets("Sheet4").Range("A1").Select ActiveSheet.Paste Range("A1").Select Sheets("Sheet1").Select Selection.AutoFilter Application.ScreenUpdating = True Sheets("Sheet1").Range("A1").Select MsgBox "振り分けが完了しました。" '****コピー貼り付けはここまで **** Microsoft Visual Basicの画面を×で閉じます。 使い方は、Altキー押しながらF8キーを押します。 マクロのダイアログが表示されるので先ほど名前を付けたマクロを選択して「実行」をクリック。 (選択されている状態でしたら、そのままEnterキーで実行されます。) 各シートに抽出されていると思います。

asahijp
質問者

お礼

回答どうもありがとうございます。マクロでも色々やり方があるみたいですね。教えてもらったやり方についても勉強してみたいと思います。どうもありがとうございました。

  • izmlz
  • ベストアンサー率55% (67/120)
回答No.1

抽出先のシートで、[フィルタオプションの設定]をすれば良いかと思います。 詳しくは以下のページをご覧ください。 エクセル技道場-別シートにデータを抽出 http://www2.odn.ne.jp/excel/waza/edit.html#SEC37 なお、同じシートで抽出するのなら、[オートフィルタ]ボタンをメニューバーあるいはツールバーに登録しておけば簡単です。↓をご覧ください。 http://www2.odn.ne.jp/excel/waza/edit.html#SEC19

参考URL:
http://www2.odn.ne.jp/excel/waza/edit.html#SEC19
asahijp
質問者

お礼

回答いただきましてありがとうございます。関数やVBAにこだわっていましたが、フィルタオプションを使えばもっと楽にできることがあるのですね。勉強になりました。ありがとうございます。

関連するQ&A

  • エクセルでの関数について

    初めて質問します。解る方がいたら教えていただきたく書き込みします。エクセルで台帳を作成するため、sheet1に次の通り情報を入力しました。    A  B    C     D 1 日付 名前  住所   申請事由   2 1/1 甲川  東京都    1 3 1/2 乙本  大阪府     1 4 1/2 丙藤  北海道    2 5 2/1 甲山  京都府     3 ・ ・  ・  ・        ・ そして、sheet2に申請事項1の人の情報を、sheet3に申請事項2の人の情報を、sheet4に申請事項3の人の情報を空白を開けずに次の通り詰めて入力したいのです。 sheet2(申請事由1の人)     A      B      C 1  日付  名前   住所 2  1/1 甲川  東京都 3   1/2 乙本  大阪府 4 ・   ・    ・ sheet3(申請事由2の人)     A      B      C 1  日付  名前   住所 2  1/2   丙藤  北海道 3 ・   ・    ・ 4 ・   ・    ・ sheet1に日付、名前等を入力しただけで、各事由事に他のsheetに詰めて入力されるよう関数式で入力することは可能かどうか教えてください。よろしくお願いします。

  • VBAで一定期間の名簿を検索、抽出できますか?

    お世話になっております。皆さんよろしくお願いします。 Aという名前のエクセルファイルのsheet1に次のような名簿が入力してるとします。   A     B    C     D 1 申請日  名前   住所  電話番号 2  4/1   甲   東京   00-0000 3  4/2   乙   大阪   11-1111 4  4/3   丙   京都   22-2222 ・  4/3   虎   北海道  33-3333    ・  ・    ・   ・     ・ こういう名簿が3000件くらいあります。申請日は一件しかない日もあれば、数百件ある日もあります。また、申請日は一概に4/1から順になっていないところもあります。 この名簿を他のBというエクセルファイルに指定した期間ごとに抽出したいと考えています。 例えば、Bファイルのsheet1に、   A     B    C     ~  G 1 4/3    4/4   4/5    ~  4/9 と一週間分を入力し、コマンドボタンを押したら、Bファイルのsheet2 に、   A     B    C     D 1 申請日  名前   住所  電話番号 2  4/3   大田   京都   22-2222   3  4/3   佐藤   北海道  33-3333    ・  ・    ・    ・    ・ ・  ・    ・    ・    ・ 11  4/9    山田   愛知  44-4444    できたら嬉しいのですが、できるのでしょうか?どなたかお知恵をお貸しください。 よろしくお願いします。

  • エクセルのVBAを勉強中

    VBAの勉強をしております。 初心者なので、なんでこんなの分からんの!と言わず、教えていただけたらと思います。 シート1のA2からD2まで入力したものを、コピーしてA4からD4に貼り付けるという式は、下記でいけると思いますが、 シートをまたいだ時はどうなるのでしょうか。 例えば、A2からD2まで入力したものを、シート2のA4からD4に貼り付ける場合は、どうなるのでしょうか。 また、シート1のA2:D2までの入力を何度か繰り返した場合、シート2への貼り付けが、A5:D5、A6:D6、A7:D7とどんどん下に溜まっていく式を教えてください。 Range("A2:D2").Copy Destination:=Range("A4:D4")

  • エクセル 抽出方 教えて下さい

    sheet1に    A    B      C       D        E        F 1 名前  住所  2011/4/22  2012/4/22  2016/4/22  2021/4/22 と(C1は入力日付D1~F1には関数でN年後の日付が入力)縦に 500件程あります。D~Fのデータの中で指定したたとえば2016年5月が含まれるA~Fまでの表を抽出がしたいのですがどうしたらできるのでしょうか?できれば別シートに抽出結果を表示したいです。 オートフィルタでも関数でも構いません。ご教示お願い致します。 OS WindowsXP pro Office Excel 2003 です。

  • VBA

    エクセルVBAについて教えてください。 シート1 A列   B列   C列   D列   E列    F列 ・・・            商品A  商品B  商品C  商品D・・・ 日付  名前(1)   3           2     1 日付  名前(2)         1     3  ・     ・     ・     ・     ・    ・  ・     ・     ・     ・     ・    ・  ・     ・     ・     ・     ・    ・ シート2 A列   B列    C列    D列    E列 日付  名前(1)   商品A   3               商品C    2               商品D    1 日付  名前(2)   商品B    1               商品C    3 ・      ・      ・      ・  ・      ・      ・      ・ ・      ・      ・      ・      上記のような、エクセルで作ったシート1があります。 これを、シート2のようにコピーしたいと思っています。 商品は20列あり、数字が入っている列と入っていない列があります。 数字が入っている列の商品と数字をコピーして、すべてコピーが 終わったら次の行のコピーしていく。 行は100ほどあります。 よろしくお願いします。

  • エクセル

    シート1~5まであります。別に情報シートを作成しています それぞれ同じ原本から作成しています 全部のシートにA1~A10のセルに日付、B1~B10のセルに文字など入力がするところがあります 入力はA1から順番に入れていきます 例えば 保存ボタンを作成しておく シート1のA1に日付、B1に”文字”を入力し、保存ボタンをおす 情報シートに日付と内容が一致する情報がなければ、 情報シートのA列にシート名、B列に日付、C列に入力した内容が 空白のところに出力される こんな感じに作成できないでしょうか?

  • エクセルVBAについて

    こんにちわ! 今、エクセルでAシートの入力した項目をBのシートへデーターが入力できるようなシステムを以下のようにくみました。 そこでBシートにデーターが入力されるのですが20行まで入力すると入力できないようにしたいのですが、なかなか上手くいきません。 A1からF20まで書式のロックを外しそれ以外のセルは保護をかけたのですがその状態でVBAを使って20行以上入力できませんという感じのエラー表示をしたいのですが、どうすればいいでしょうか? VBAは初心者ですが宜しくお願いします。 Private Sub CommandButton1_Click() Dim row As Integer row = WorksheetFunction.CountA(Sheets("date").Columns(1)) + 1 Sheets("date").Cells(row, 1).Value = Range("B2").Value row = WorksheetFunction.CountA(Sheets("date").Columns(2)) + 1 Sheets("date").Cells(row, 2).Value = Range("B3").Value row = WorksheetFunction.CountA(Sheets("date").Columns(3)) + 1 Sheets("date").Cells(row, 3).Value = Range("B4").Value row = WorksheetFunction.CountA(Sheets("date").Columns(4)) + 1 Sheets("date").Cells(row, 4).Value = Range("B5").Value row = WorksheetFunction.CountA(Sheets("date").Columns(5)) + 1 Sheets("date").Cells(row, 5).Value = Range("B6").Value row = WorksheetFunction.CountA(Sheets("date").Columns(6)) + 1 Sheets("date").Cells(row, 6).Value = Range("B7").Value Sheets("統制入力").Select Range("B17").Select ActiveWindow.SmallScroll Down:=-9 Range("B3:B7").Select Selection.ClearContents Range("B1").Select End Sub

  • エクセルのVBAで

    日付を入力したシートでシートを開くと今日の日付のセルがあった場合左上に表示させるモジュールで、 Sub test() Dim R As Range Set R = Range("A:A").Find(Date) If Not R Is Nothing Then Application.Goto reference:=R, scroll:=True End If End Sub のように作成したのですが、うまく働きません。 原因は、日付を表示したセルが、A1に2006/4/1を入力してA2以降のセルはA1+1、A2+1・・・で対応しています。 よって、アクションが働かないのではと推測しているのですが、このことを改善するにはどのようにしたらいいでしょうか? 日付をダイレクトに入力しないのは、2007年にも先頭セルのみの書き換えで対応しようとしたためです。

  • ExcelのVBAについて

    すみません、ご教授下さい。 エクセルVBAで簡単な住所録のようなものを作りたいのですがご教授頂けますでしょうか? 内容としては、シート1に入力フォームがあり、登録ボタンを押すと シート2へ一覧していく形です。 また、シート2に一覧していく際は新しいものが上に挿入され、 入力フォームはクリアされるという形になります。 シート1   A    B 1 顧客ID AAA 2 姓    サンプル 3 名    太郎 4 TEL   080-0000-****  →これ以降も項目を増やします。 シート2     A    B      C     D 1 顧客ID   姓     名    TEL 2  AAA   サンプル 太郎 080-0000-**** ご教授頂けますでしょうか? 何卒宜しくお願い致します。

  • エクセルVBAについて教えてください

    エクセル2003 シート1     A       B      C 1  3月1日 A 100     *A列はカレンダーコントロールより選択としています 2  4月1日 B 100 3  3月1日 C 200     *B列はコンボボックスより選択としています 4  3月1日 D 200 5  4月1日 E 300     *C列は直接入力としています 6  4月1日 F 300 7  3月1日 G 100 8  4月1日 H 200 9  3月1日 I 200 10  4月1日 J 100 上記シート1の表のC列を下記シート2のC列に条件集計する シート2    A       B       C 1  3月1日   A~E     500    *選択した日付ごと及びA・B・C・D・Eの集計  2  3月1日   F~J     300    *選択した日付ごと及びF・G・H・I・Jの集計     3  4月1日   A~E     400    *選択した日付ごと及びA・B・C・D・Eの集計    4  4月1日   F~J     600    *選択した日付ごと及びF・G・H・I・Jの集計  すいませんが上記コードを教えてください 困ってます よろしくお願いします      

専門家に質問してみよう