[[20221006123903]] 『何故かエラーに・・・』(Kozzy) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『何故かエラーに・・・』(Kozzy)

質問させてください。

プロシージャ内の変数をMatchでセルの位置を取得しようとするとエラーになりました。

変数:TargetValue
Application.WorksheetFunction.Match(TargetValue, Worksheets("ホーム").Range("C:C"), 0)

それで変数の値を確認しながらステップ実行で進めると、
どう考えても同一の値なのにエラーが出ていました。

イミディエイトウインドウで確認しても同じ値、同じVartypeでした。

そこで検索範囲内にあるセル値でMatchを使ってみると
application.WorksheetFunction.Match(worksheets("ホーム").cells(12,3).value,worksheets("ホーム").range("C:C"),0)
これでもエラーになりました。

原因は分かりますでしょうか?

< 使用 Excel:unknown、使用 OS:unknown >


シート、セルの値のような要素を変数に入れて分離して、
エラーの出るところが変わるか調べてみてはいかがでしょう
(火災報知器) 2022/10/06(木) 12:57

application.WorksheetFunction.Match(worksheets("ホーム").cells(12,3).value,worksheets("ホーム").range("C:C"),0)

これをイミディエイトウィンドウで実行してもエラーなのです。
実行時エラー '1004':
WorksheetFunction クラスのMatch プロパティを取得できません。

(Kozzy) 2022/10/06(木) 13:07


 TargetValueの型はなんですか?
 TargetValueに入れた変数の型はなんですか?

 例えば、以下のコードは、
 C1に1が入力されているはずなのに、
 1をMATCHで検索しようとしてエラーになります。 
 型があっていないからです。

 Sub sample()
  Dim TargetValue As String

  Worksheets(1).Range("C:C").ClearContents   'いったんクリア

  Worksheets(1).Range("C1").Value = 1
  TargetValue = 1

  Debug.Print Application.WorksheetFunction.Match(TargetValue, Worksheets(1).Range("C:C"), 0) ' これエラー
 End Sub

 エラーの発生行の前後も見ないとエラー原因はわかんないんですよ
(´・ω・`) 2022/10/06(木) 13:13

 Sub 確認()
   Dim ws As Worksheet
   Dim rng As Range
   Dim TargetValue
   Set ws = Worksheets("ホーム")
   Set rng = ws.Range("C:C")
   TargetValue = ws.Range("C1").Value
   Debug.Print Application.WorksheetFunction.Match(TargetValue, rng, 0)
 End Sub

(火災報知器) 2022/10/06(木) 13:29


TargetValueの型はDateです。
ヒットさせたいセルはC12セルで、

?(TargetValue = Worksheets("ホーム").Cells(12,3).Value)
はTrueで
?(VarType(TargetValue) = Worksheets("ホーム").Cells(12,3).Value)
もTrueです。

コードは

    '支払済みのシート(先月分まで)を性能検査申し込み履歴(支払い済み).xlsxに転写する
    Dim xlsF As WorksheetFunction
    Set xlsF = Application.WorksheetFunction

    '転写先、転写元のブックを格納
    Dim InportBook As Workbook, ExportBook As Workbook
    Set InportBook = GetHistoryBook
    Set ExportBook = ThisWorkbook

    '転写元のホームシートを格納
    Dim HomeSheet As Worksheet
    Set HomeSheet = ExportBook.Worksheets("ホーム")

    '転写元シート数を取得
    Dim cnt As Long
    cnt = ExportBook.Worksheets.Count
    ReDim SheetName(cnt) As String

    '先月までの支払い済みシートを探す
    Dim SetUp As New SetUp
    Dim y As Long, m As Long, r As Long, Num As Long, StartCount As Long, EndCount As Long
    Dim NowMonth As Date, TargetValue As Date
    NowMonth = SetUp.PaymentMonth(Val(Year(Now())), Val(Month(Now())) - 1)

    With HomeSheet
        For r = 3 To cnt + 2
            TargetValue = .Cells(r, 3).Value
            If TargetValue > 0 Then
                If TargetValue < NowMonth Then
                    If Num = 0 Then
                        Num = TargetValue
                        StartCount = xlsF.Match(TargetValue, .Range("C:C"), 0)
                    ElseIf Num <> TargetValue Then
                        Num = TargetValue
                        EndCount = xlsF.Match(TargetValue, .Range("C:C"), 0)
                    End If
                    SheetName(r - 2) = .Cells(r, 2).Value
                Else
                    If Num = 0 Then GoTo EndProcedure
                    Exit For
                End If
            End If
        Next r

        StartCount = .Cells(StartCount, 1).Value
        EndCount = .Cells(EndCount, 1).Value

    End With

    '先月までの支払い済みシートを転写、転写後に元シートを削除
    Dim idx As Long
    For idx = StartCount To EndCount
        With ExportBook.Worksheets(SheetName(idx))
            cnt = InportBook.Worksheets.Count
            .Copy After:=InportBook.Worksheets(cnt)
            Application.DisplayAlerts = False
            .Delete
            Application.DisplayAlerts = True
        End With
    Next idx

EndProcedure:

    '性能検査申し込み履歴(支払い済み).xlsxを閉じるのとオブジェクトの開放
    Set InportBook = CloseHistoryBook(InportBook)
    Set ExportBook = Nothing
    Set HomeSheet = Nothing
    Set xlsF = Nothing

End Sub

ですが、そもそも
?application.WorksheetFunction.Match(worksheets("ホーム").cells(12,3).value,worksheets("ホーム").range("C:C"),0)
がエラーになるのはおかしくないですか?
(Kozzy) 2022/10/06(木) 13:41


火災報知器さん>
そのコードでも同じくMatch部分で'1004'エラーです。
※C1セルは空白のため、値のあるC列のセルに変えました。
(Kozzy) 2022/10/06(木) 13:45

>TargetValueの型はDateです

worksheets("ホーム").cells(12,3).value2
または
worksheets("ホーム").cells(12,3)
としてください

(マナ) 2022/10/06(木) 13:49


マナさんに補足するとTargetValueの型はバリアント型またはDouble型に変更
(火災報知器) 2022/10/06(木) 13:57

火災報知器さん>
宣言をDateからDoubleに変更するとエラーはなくなりました。
ありがとうございます。

過去に一回は動かしたことがあるのですが、なぜでしょうね・・・

しかし別件でプログラムの不具合が起こったので、別の案を考えてみます。

みなさま、ありがとうございました。

(Kozzy) 2022/10/06(木) 14:24


マナさんへの返信が消えていました、すみません。

マナさん>
Value2にするとイミディエイトウィンドウでのエラーはなくなりましたが、
実際に動かすとエラーのままでした。
(Kozzy) 2022/10/06(木) 15:19


無いからエラーになると言う事。
WorksheetFunction を取っ払うか、エラートラップ。
(カワキ外伝) 2022/10/06(木) 16:14

カワサキ外伝さん>

VBAでヒットしないだけで同一データはありますが。
エクセル上ではMatch関数はエラー値になりませんし。
(Kozzy) 2022/10/06(木) 17:08


 日付をMATCH関数で検索するのはちょっと癖があります。

 >Value2にするとイミディエイトウィンドウでのエラーはなくなりましたが、
 >実際に動かすとエラーのままでした。
 実際に動かしたコード書いてください

 Date型変数にValue2プロパティを代入しちゃったら、同じことです

 MATCH関数に渡すときにCDblで明に型変換してもいいです。
 Debug.Print Application.WorksheetFunction.Match(CDbl(TargetValue), Worksheets(1).Range("C:C"), 0) 
(´・ω・`) 2022/10/06(木) 17:19

>Double

日付だけじゃなく時間も入っているのかな?
(カワキ外伝) 2022/10/06(木) 17:38


(´・ω・`)さん>
>実際に動かしたコード書いてください
上に提示したコードです。
まあ自作関数も使っているので、そちらで試すことは出来ない部分がありますが。

>Date型変数にValue2プロパティを代入しちゃったら、同じことです
普段はValue2プロパティを全く使わないで特に不具合がなかったので、よく考えずに使いました。

>MATCH関数に渡すときにCDblで明に型変換してもいいです。
そういう方法もあるんですね、勉強になります。
でもその部分だけ型変換するなら、最初からDoubleで宣言しちゃうのが早い気はしますね。
自分が組んだコードなら。

カワキ外伝さん>
エクセルに入力されてある日付も別マクロで入力された値なんで、時間はない・・・はず。

まぁ結局のところ、C列で年月がヒットする区間行を取得したいだけなので、
C列の検索範囲を取得してからループって方法に変えました。

(Kozzy) 2022/10/07(金) 08:44:02


日付だけなら、一般的に long型では。

Match(シリアル値,範囲・・・

それと、Value2で見つからないというのが???
Value2は、セルの内容が日付の場合シリアル値で取得します。
なんか話がかみ合ってないようにも。
かみ合わないので手を引いた方が良いのかも。

(カワキ外伝) 2022/10/07(金) 09:10:29


 Sub test()
     With Range("A1")
         .Value = Date
         Debug.Print TypeName(.Value2)
     End With
 End Sub

 Doubleが返りますので、Double型で受けるのが常識的でしょう。
 まぁ、そんなに拘ることでもないですが。

 >application.WorksheetFunction.Match(worksheets("ホーム").cells(12,3).value,worksheets("ホーム").range("C:C"),0)
 >これでもエラーになりました。
 そもそもこの検証がおかしい。
 第一引数が日付なら、Valueプロパティで検索するのは間違い。(マナさんのレスの通り)

(半平太) 2022/10/07(金) 10:12:04


横から失礼します。
Double型の説明を読むと、倍精度浮動小数点型のとおり小数点を扱うとあります。
半平太さんの回答の、日付(シリアル値)をタイプ判定したらdouble型が返る理屈が分かりません。
ネット上のコードでも、日付を扱うときにdate型ではなくdouble型を使用する例をよく見る(気がする)んですが、参考になるサイト等あれば知りたいです。
頓珍漢なこと言ってたらすみません、、、
新規でスレを立てたほうがよかったら移動します。
(VBA勉強中) 2022/10/07(金) 23:00:05

 >Double型の説明を読むと、倍精度浮動小数点型のとおり小数点を扱うとあります。
 >半平太さんの回答の、日付(シリアル値)をタイプ判定したらdouble型が返る理屈が分かりません。

 あのー「.Value2」プロパティですよ。
    「.Value」 プロパティではないですが。

 ヘルプより
 >Value2 プロパティでは、通貨型 (Currency) および日付型 (Date) のデータ型を使用しない点のみが、Value プロパティと異なります。
 >倍精度浮動小数点型 (Double) を使用することにより、これらの 2 種類のデータ型の値を浮動小数点数として返すことができます。

 >ネット上のコードでも、日付を扱うときにdate型ではなくdouble型を使用する例をよく見る(気がする)んですが、
 私はちょっと分からないです。
 一般論として、Date型はバグが出るので、使わないで済むならそれに越したことはないです。

(半平太) 2022/10/07(金) 23:15:17


説明ありがとうございます。
Value2プロパティのヘルプをしっかり読んでませんでした。

 >倍精度浮動小数点型 (Double) を使用することにより、これらの 2 種類のデータ型の値を浮動小数点数として返すことができます。
やっぱり浮動小数点の理解ができていないので、勉強してきます。

 >一般論として、Date型はバグが出るので、使わないで済むならそれに越したことはないです。
勉強になります。

Kozzyさん場所を借りて失礼しました。
(VBA勉強中) 2022/10/07(金) 23:28:35


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.