『検索値が見つからない』(もっしゅ) 急ぎになってしまい、再度質問させて頂きます。 申し訳ありません。 下記の記述で「検索値が存在しない」というエラーがでます。 各月のシートのA列に日付がありそれをシート1のA1セルで プルダウンメニューを使い指定しています。 Sub 売上実績() Dim rng As Range Dim i As Long For i = 1 To 2 Set rng = Worksheets(i & "月").Range("A:A").Find( _ What:=Worksheets("1").Range("A1").Text, _ LookIn:=xlValues, _ LookAt:=xlWhole) If rng Is Nothing Then MsgBox "検索値が存在しません", vbCritical Else rng.Offset(0, 1).Value = Sheets("1").Range("A1").Offset(0, 1).Value End If Next i End Sub 宜しくお願いします! ---- 前スレで気になったので、 >シート"1"のA1と、それ以外のA列の「日付」のデータ型式が「日付型」で表示書式が同じものという前提だね。 とコメントした。 日付の検索はFindに限らずやっかいなものだけど、Findで検索する場合は ・WhatをValue、LookInをxlFormulas が王道かな? ・提示の形で行う場合は、検索する値と検索する範囲の「表示書式」が同じでなければヒットしない。 それと、ついでに。前スレで、シート"1"以外に、特定のシートも除外するなら If Not sh Is Worksheets("1") Then これを If Not sh Is Worksheets("1") And Not sh Is WOrkSheets("特定のシート名") Then (ぶらっと) ---- シート1のAセルをプルダウンで〜っていうのは入力規則で設定してるのかな? 日付は「1日」とかで記述してるの? プルダウンの入力規則(設定してるなら)と入力の型式、それとシート1と他のシートのA列の書式設定が合っているかを教えてください。 (マッキー) ---- 追記 まさかとは思うけど念のため。 1月は31日まで、2月は28日もしくは29日まで。 30日や31日を指定したら当然「検索値が〜」になる。 そこの処理はどうするのかな。 あと [[20111214154457]] の >全ての月の日付をまとめたシートがあり >そのシートだけ除外する記述はありますでしょうか? 私のはぶらっとさんのほど精巧ではないので「1月」〜「12月」というシートしか相手にしていないから まとめたシートの名前が「1〜12月」の間になかったらそのシートは除外されてます。 (マッキー) ---- 急ぎの割にはレスがないけど。 Find検索やまとめシートの除外についてはコメント済みだけど、あわせて、今回の場合は 処理すべき日付は各シートに1つのみのようなので、Findを使うまでもなくMatchで充分。 そういったことを加味すれば Sub Sample2() Dim sh As Worksheet Dim mySh As Worksheet Dim ngSh As Worksheet Dim ans As Variant Set mySh = Sheets("Sheet1") '入力規則のあるシート Set ngSh = Sheets("まとめシート") '処理対象外のシート For Each sh In Worksheets If Not sh Is mySh And Not sh Is ngSh Then sh.Columns("B").ClearContents ans = Application.Match(mySh.Range("A1").Value, sh.Columns("A"), 0) If IsNumeric(ans) Then sh.Range("B" & ans).Value = mySh.Range("B1").Value Else MsgBox sh.Name & "に検索値が存在しません", vbCritical End If End If Next Set mySh = Nothing Set ngSh = Nothing End Sub (ぶらっと) ---- おそくなりすみません。 結局間に合わなかったのですが、その部分以外を除いてみせて事な気をえました。 戻ってきてからテスト用ファイルのマクロを使用するファイルに移したらなぜか改善されましたので引き続き皆様のを参考にやってみます。 ちなみに、書式の表示形式もまったくいっしょです。 ぶらっどさん 急ぎと書いておいておそくなりすみません。 上のやつでも試してみます。ありがとうございます>< ---- マッキーさん プルダウンは入力規則でやっています。 表示形式は「d"日"」です。 おそくなり申し訳ないです。 もっしゅ ---- おかげさまで検索値の問題は解決できたのですが もしかしたら根本的に質問の間違いを犯していたかもです。。すいません 今度は月別に分けているシート全ての日付に飛んでしまいます。 1/1を指定すると1〜12月の1日に全て張り付けられてしまいます。 宜しくお願いします。 もっしゅ ---- 別スレ含めて何度も言っているけどセルのTextを使ってxlValuesのFind検索を行うと、見た目の一致。 つまり表示書式が d"日"ということだから、すべての月のその日にマッチするよ。 (レスを理解して読んでくれてたのかなぁ) やるなら、セル.Value で LookIn:=xlFormulas。 あるいは、上でアップしたSample2のようなコードでMatch検索。 それより、各シートにすべて一年の日付があるんだと思ってたけど、そうじゃなく 12月は12月のシートだけの処理? それならシートをループして処理するんじゃなく、Sheet1のA1の日付の月のシートのみを対象にすべき。 (月とシート名に関連づけルールがあるということが必要だけど) ★その場合でも、Findの留意点は同じだよ。 (ぶらっと) ---- あれ? 私はてっきり >12シートつまり貼り付ける記述の部分?を12月分まで >増やせる方法はありますでしょうか? と書いてあったからシート"1"に入れた内容を全ての月に適用したいのだと思ってました… そうじゃなくてシートを特定して貼りつけたいってこと? 例えば「1月と3月と12月に貼りつけたい」とか複数シートを指定したいのか、「12月のシート」と一つを指定したいのか… ごめんなさい、やりたいことがよくわからない 中途半端に私が手を出すよりぶらっと様に任せた方がよさそうな気がしてきた…^^; (マッキー) ---- ぶらっどさん まさに12月のは12月と言う処理をしたかったかんじでした・・・ めちゃくちゃな質問に明確な回答有難うございます。 参考にしてもう一度やってみて報告します。 まっきーさん まさにシート一つを特定したいということです。 12月1日は12月のシートの1日のセル横という感じで。。。。 めちゃくちゃで申し訳ない。 もっしゅ ---- >質問者さん とりあえず落ち着いて、書いてある事読んだらどうですか〜? 見落としや見間違いは無いですか〜? 例えばぶらっとさんの名前とか・・・ (とおりすがりん♪) ---- ぶらっとさんのを参考にやってみています。 Sub Sample2() Dim sh As Worksheet Dim mySh As Worksheet Dim ngSh As Worksheet Dim ans As Variant Set mySh = Sheets("Sheet1") '入力規則のあるシート Set ngSh = Sheets("まとめシート") '処理対象外のシート For Each sh In Worksheets If Not sh Is mySh And Not sh Is ngSh Then sh.Columns("B").ClearContents ans = Application.Match(mySh.Range("日付選択セル").Value, sh.Columns("日付検索列"), 0) If IsNumeric(ans) Then sh.Range("貼り付け列" & ans).Value = mySh.Range("貼り付けセル").Value Else MsgBox sh.Name & "に検索値が存在しません", vbCritical End If End If Next Set mySh = Nothing Set ngSh = Nothing End Sub という認識でよろしいでしょうか? 混乱させて申し訳ございません。 ---- >という認識でよろしいでしょうか? 基本、アップしたコードそのままなので、この認識でいいかどうかという質問そのものの意図が?だけど。 ただ、セル指定、列指定を名前を登録してそれを使うようにしたんだね。 これでやってみた? たぶん、これじゃだめだと思うけど? まず、領域の名前は「ブックレベル」のものがある。これは、どのシートがアクティブになっていようと その名前で領域を指定することができる。 また「シートレベル」のものがある。これは、アクティブになっているシートのにその名前があれば、そのセルを参照。 なければ、ブックレベルの名前のセルを参照する。 エクセルが2003以前か2007以降かで、指定方法は異なるけど基本は同じ。 (もっしゅ)さんは、具体的に、どこに、どのようにそれぞれの名前をつけたのかな? いずれにしても、名前がついたセルを、シート.Range("名前") で参照するとエラーになる。 単に、Range("名前") として参照することが必要。さらに、"日付検索列" は、おそらくどこかの列全体に 名前をつけているんだろうけど、Columns("日付検索列")はだめ。これもRange("日付検索列")と、Rangeで指定する。 もう1つ気になることがある。 入力規則で日付リストから選ばせる。その表示書式はd"日"なので、実際にリストに表示されるのは、1日、2日、3日、・・・ だよね。でも実際には、リスト内の値はyyyy/mm/dd だよね。何年の何月の日付がリストとして登録されているんだろう? 2011年8月の日付だったとして、そこから選んだ10日は、2011/8/10 だということは認識してる? で、かりに、これですべてのシートをループさせれば、8月のシートの10日がヒットする。 それじゃ具合悪いんでしょ? 本来は、こちらから指摘している事項、シートをループさあせる必要はなく、選んだ日付の月のシートのみを検索 すればいいんだけど、その前に、この入力規則の日付の問題を解決しなきゃね。 いくつか方法はある。 1.入力規則の日付リストを1年分にする。表示はd"日"じゃぐあいわるいので月が表示されるようにしておく。 でも、「非現実的」。たとえこうしておいても、来年になれば、また変更しなきゃいけないし。 2.年月を指定する入力規則セルと日を指定する入力規則セルをわけておく。で、両方を連結したものを指定日とする。 3.年、月、日 それぞれ別の入力規則セルにする。  年はあらかじめ何年分かをいれておく。月も1〜12をいれておく。年と月が入力されれば、その月の日をマクロでセットする。 3.が一番いいように思うな。 (ぶらっと) ---- >まず、領域の名前は「ブックレベル」のものがある。これは、どのシートがアクティブになっていようと >その名前で領域を指定することができる。 このレス、不正確なので訂正。正しくは まず、領域の名前は「ブックレベル」のものがある。 実行時にアクティブになっているシートに「シートレベル」の、指定の名前のセルがあれば、アクティブシートのセル領域、 なければ、別シートに登録された「ブックレベル」のセル領域を参照する。 (ぶらっと) ---- 一応コード案。 前提 条件指定シートに、年選択セル、月選択セル、日選択セル、貼り付けセル を名前定義 年選択セルには入力規則で、2011,2012,2013 あたりを登録(再来年まで利用可能) 月選択セルには入力規則で、1,2,3,4,5,6,7,8,9,10,11,12 を登録。 日選択セルはマクロでセットするので登録不要。 シート名は、1 〜 12 の数字で作られているという前提。 各月シートの日付検索列と貼付列は名前定義ではなく、コード内のConstで規定している。 (条件指定シートのシートモジュール) Private Sub Worksheet_Change(ByVal Target As Range) Dim v As Variant Dim d As Long Dim i As Long If Not Intersect(Target, Range("年選択セル")) Is Nothing Or Not Intersect(Target, Range("月選択セル")) Is Nothing Then If Len(Range("年選択セル").Value) > 0 And Len(Range("月選択セル").Value) > 0 Then d = Day(DateSerial(Range("年選択セル").Value, Range("月選択セル").Value + 1, 0)) ReDim v(1 To d) For i = 1 To d v(i) = i Next With Range("日選択セル").Validation .Delete .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(v, ",") .IgnoreBlank = False .InCellDropdown = True .IMEMode = xlIMEModeNoControl .ShowInput = True .ShowError = True End With End If End If End Sub (標準モジュール) Sub Sample3() Const 日付検索列 As String = "A" Const 貼り付け列 As String = "B" Dim ans As Variant Dim sName As String Dim myDate As Date Dim yy As Variant Dim mm As Variant Dim dd As Variant yy = Range("年選択セル").Value mm = Range("月選択セル").Value dd = Range("日選択セル").Value If Len(yy) = 0 Or Len(mm) = 0 Or Len(dd) = 0 Then MsgBox "年月日を選択してください" Exit Sub End If sName = mm If Not IsObject(Evaluate("'" & sName & "'!A1")) Then MsgBox sName & "シートがありません" Exit Sub End If myDate = DateSerial(yy, mm, dd) With Sheets(sName) .Columns(貼り付け列).ClearContents ans = Application.Match(CDbl(myDate), .Columns(日付検索列), 0) If IsNumeric(ans) Then .Range(貼り付け列 & ans).Value = Range("貼り付けセル").Value .Select Else MsgBox "検索日付が存在しません", vbCritical End If End With End Sub (ぶらっと) ---- ぶらっとさん 大体理解できました!本当に有難うございます。 こんなに長い記述を・・・感謝です。 レイアウトが少し変わったため貼り付け列を替えました。 転記のコピー元はどの部分の記述にあたるのかが 分からないのですがどこの部分になるのでしょう?;; あと.Columns(貼り付け列).ClearContents たぶんこの記述だと思うのですが、貼り付け列を消すということでしょうか? 列全体がきえてしまうのですが。。。 すみません・・・宜しくお願いします。 ---- >転記のコピー元はどの部分の記述 転記は .Range(貼り付け列 & ans).Value = Range("貼り付けセル").Value なので、Range("貼り付けセル").Value これが転記元のセル。 このコードでは、どの日付に対しても同じセルの値が転記される。 もし、そうではないのなら、日付毎に、転記元のセルがどういった位置関係にあるのかを教えて。 >貼り付け列を消すということでしょうか?列全体がきえてしまうのですが そうだね。具合が悪ければ、.Columns(貼り付け列).ClearContents を削除して。 (ぶらっと) ---- ぶらっとさん 有難うございます。 理解できていなかった部分も上記の説明ですごくよく理解できました。 クリアコンテンツを消して、転記元のセルに名前を付けたら理想の形ができたので これで文句なしに提出できそうです。本当に助かりました。 今後はこのコードを参考にもう少し勉強しようと思います。 長々と有難うございました。 もっしゅ