質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

2回答

5945閲覧

Excel VBA ~Findで探して貼り付けたいのですが…

masa1975

総合スコア22

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2020/07/31 08:17


worksheet”登録"
|8月|列2|Co2排出量|19.95| 消費電力|38.52|TOTAL|55.83| 
|:--|:--:|--:|
||||

worksheet”年度別排出量”
|2020年|4月|5月|6月|7月|8月
|:--|:--:|--:|
|使用時間(h)|150.17 |86.21|96.42|53.4||

上の登録シートのTOTAL値55.83をコピーし、下の年度別排出シートの8月に貼り付けたいのですが
行き詰ってしまったためご教授いただけましたら幸いです。

Excel

1Sub yotei() 2 Dim ws1 As Worksheet 3 Dim ws2 As Worksheet 4 5 Dim Lastrow As Integer 6 Dim kensaku As Range 7 Dim myrange As Range 8 9 10 Worksheets("登録").Activate 11 Set ws1 = Worksheets("年度別排出量") 12 Set ws2 = Worksheets("登録") 13 14 15 Lastrow = ws1.Range("a1").End(xlToRight).Column 'A列の最終列を取得 16 ws2.Range("a4").Activate 'a4セルをアクティブに 17 18 19 20 Set myrange = ws1.Range("A1:a" & Lastrow) 'A1:Aセルの最終列を取得 21 Set kensaku = myrange.Find(what:=ActiveCell, lookat:=xlPart) 'Find関数でActivecellと同じ値がmyrangeにあるか探してkensakuに代入 22 23 ActiveCell.Offset(0, 7).Copy 24 kensaku.Offset(1, 1).PasteSpecial*ここでエラーが出てしまいます。(コード91) 25 26 'End If 27 28 29 'Loop 30End Sub

色々ネットで探しまくったのですがなぜエラーになるのかも解らず困っております。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

http://officetanaka.net/excel/vba/error/execution_error/error_91.htm

エラーが出たときは、コード番号やエラーメッセージそのもので検索してみてください。
たいていの場合、同じように困って質問している人がいるので、原因や解決策が見つかります。
今回の件の場合、
エラーが出て、デバッグのボタンでVBEの画面に戻ったときに、
ローカルウィンドウで変数の中身を確認してみてください。

変数「kensaku」の中身がNothingになってませんか?
検索した文字列と見つかってほしい文字列とが、
全角半角の違いとか
見えない文字(スペースやセル内改行等)がくっついてるとかで、見つかってないかもです。
手動の検索で見つかるかどうか試してみてください。
Findメソッドはその操作を呼び出しているだけなので挙動はほぼ同じです。
また、Findメソッドは、手動でのオプションの変更も引き継ぎますので、
たくさんの設定の記述を省略することは、誤動作の原因になります。
(期待した結果を返したり返さなかったり動作が不安定になる可能性があります。)
なので、マクロの記録で得られたコードをそのまま使用することをお勧めします。
絶対大丈夫だという自信があれば省略してもいいですが。

同じようにActiveCellも、コロコロ変わるものなので、
できれば使わないようにした方が安全です。
直前でアクティブにしているので、間違いはないかと思いますが、
ちょっと怖いです。

僕なら以下のようにします。

ExcelVBA

1Sub 予定転記2() 2 Dim rngFrom As Range 3 Dim rngTo As Range 4 Dim ixCol As Variant 5 6 With Worksheets("登録").UsedRange 7 Set rngFrom = .Rows(.Rows.Count) 8 End With 9 Set rngTo = Worksheets("年度別排出量").Rows(1) 10 11 ixCol = Application.Match(rngFrom.Cells(1).Value, rngTo, 0) 12 13 If Not IsError(ixCol) Then 14 rngTo(2, ixCol).Value = rngFrom.Cells(rngFrom.Cells.Count).Value 15 Else 16 MsgBox "転記先の書き込む項目が見つかりませんでした。" 17 End If 18End Sub

参考になれば。
動作確認してません。
セルの位置関係や、シートの指定が間違っていたり、
こちらの勘違いで、うまく動かない場合はまた言ってください。
あと、わからないところ、気になるところがあれば聞いてください。
どこが分かってどこが分からないかがこちらではわかりませんので、
説明はとりあえず省略します。

投稿2020/07/31 09:58

mattuwan

総合スコア2163

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masa1975

2020/07/31 21:00

ありがとうございます。 ixCol = Application.Match(rngFrom.Cells(1).Value, rngTo, 0) の場所で : ixCol : エラー 2042 : Variant/Errorと出てしまいます。調べたらN/Aだかららしいのですが 何故でしょう? ちなみに(登録)のA4セルと同じ値が(年度別排出量)A1の行にあるか探して、あった場合に一つ下の行に (登録)のH4を貼り付けるといった内容です。forで回した方法をベストアンサーに選ばせていただきましたが、教えて頂いたことは覚えたいので教えて頂けると幸いです。 よろしくお願いいたします。
mattuwan

2020/08/01 00:11

>Application.Match(rngFrom.Cells(1).Value, rngTo, 0) は、ワークシート上で使うMatch関数をVBAで呼び出しているだけです。 検索値が見つからない場合は、Match関数は#N/Aを返します。 なぜか? 検索値を間違って指定している。 検索範囲が間違っている。 検索範囲の文字列と検索値の文字列が画面上区別がつかないほど似ているけど、 厳密には違う。 シート上の数式ではうまくできそうですかね?
masa1975

2020/08/01 20:03

コメントありがとうございます。 そういう事なんですね。 確認してみます。 ありがとうございました。
guest

0

ベストアンサー

下記のようにされていますが

Lastrow = ws1.Range("a1").End(xlToRight).Column 'A列の最終列を取得

この部分は、A列の最終行ではなく、A1を起点として右に検索しているので
Lastrowは6列目(F)が最大ということを示しています。

また、Set myrange = ws1.Range("A1:a" & Lastrow) 'A1:Aセルの最終列を取得

の部分は、A列の下にむかって処理するとしています。

worksheet”年度別排出量”のデータは縦展開ではなく、横展開なので
A列の最大行を取得したい理由がわかりません・・。

結果、FINDの指定もめちゃくちゃくなりますので、少し情報を整理したほうがよいと思います。

データ数が少ないので、まずは、下記のようにFINDを使わない方法で
データの指定方法について理解をしたほうがFINDで処理できると思います。

参考程度で結構です。。

VBA

1Sub test() 2 3Dim ws1 As Worksheet 4Dim ws2 As Worksheet 5Dim Lastcoumns As String 6Dim i As Double 7Dim key As String 8Dim mymonth As String 9Dim mystr As String 10 11Set ws1 = Worksheets("年度別排出量") 12Set ws2 = Worksheets("登録") 13 14Lastcoumns = ws1.Range("a1").End(xlToRight).Column 15 16key = ws2.Range("A1").Value 17mystr = ws2.Range("H1").Value 18 19For i = 1 To Lastcoumns 20 21 mymonth = ws1.Cells(1, i).Value 22 23 If mymonth = key Then 24 25 ws1.Cells(2, i).Value = mystr 26 27 28 End If 29Next 30 31Set ws1 = Nothing 32Set ws2 = Nothing 33 34End Sub

データ便にUPしておきます。ダウンロード期間は2日間です。
必要であればダウンロードしてください。

https://www.datadeliver.net/receiver/file_box.do?fb=9a132233876d4b4db2693b816cca2ac0&rc=001cb174404346c687b9197920f7c4f7&lang=ja

また、このように、表を縦持ちとして、処理するのが、質問者さんの
FINDでやりたい形式かもしれませんね!

西暦使用時間
20201月XX
20202月XX
20203月XX
20204月XX
20205月XX
20206月XX
20207月XX
20208月55.83

投稿2020/07/31 08:45

編集2020/07/31 09:34
mako1972

総合スコア383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masa1975

2020/07/31 20:46

ありがとうございます。 勉強不足&理解不足でやっていたため、頭がゴチャゴチャになっておりました。 教えて頂いた内容、とてもしっくりきました。 ありがとうございました。
masa1975

2020/07/31 21:24

おはようございます。参考にさせていただきます。
mako1972

2020/07/31 21:59 編集

変数の宣言がおかしいですね。 Dim Lastcoumns As Stringの部分は Dim Lastcoumns As doubleとか Dim Lastcoumns As integerとかでしたね。
mako1972

2020/08/01 01:17 編集

データ便に、表を縦持ちした、FIND例もUPしておきます。 必要であればですけど。ダウンロード期間は1日です (コードのコメントは少し適当だったようなので無視してください)。 https://www.datadeliver.net/receiver/file_box.do?fb=d84e7830e0234a9eb85ebbe99cb3ff0a&rc=8ffa352c8eae41519c427df57036f6bd&lang=ja 他の方がおっしゃっているとおり、Active、 select、 CopyをVBAで使うと思わぬエラーで はまることが多いので使わない方法を検討されたほうがよろしいかと思います。 また、データベースとして表を作成する場合は、理由がなければデータは縦に作成したほうが エクセル関数やマクロとの相性がよいと思います。 理由は列名や列の名称が固定で変わらないためです。 横に検索するのは何か理由があるときのみにしたほうが、混乱を避けられるという意味です。 エラー処理などは入れていませんが・・。少ないコードで検証してほしいという意味で。では。
mako1972

2020/08/01 03:12

もともとのご質問の回答だけさせてください。 ご質問内容の横持データのFIND処理ですと、下記のように記述できます。 念のため載せておきますね。 Sub myfind() Dim ws1 As Worksheet Dim ws2 As Worksheet Dim Lastcoumns As Double Dim key As String Dim mymonth As String Dim mystr As String Set ws1 = Worksheets("年度別排出量") Set ws2 = Worksheets("登録") Lastcoumns = ws1.Range("a1").End(xlToRight).Column ’最大列番号を取得 key = ws2.Range("A1").Value mystr = ws2.Range("H1").Value Set myrange = ws1.Range(Cells(1, 1), Cells(1, Lastcoumns)) '検索範囲をセット kensaku = myrange.Find(What:=key).Column '検索範囲で列番号を取得 ws1.Cells(2, kensaku).Value = mystr ’検索列の下に使用時間を転記する MsgBox "転記しました!" Set ws1 = Nothing Set ws2 = Nothing End Sub
masa1975

2020/08/01 20:01

おはようございます! なるほど~、とても分かりやすく丁寧に教えて頂きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問