[[20120229110032]] 『VBAで呼出エラー』(許斐) ページの最後に飛ぶ

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

 

 『VBAで呼出エラー』(許斐)
 たびたびすみません。先日教えていただいたコードを加工して
 使用したところエラーが出てしまいうまくいきません><
 また教えてください。よろしくお願いします。

 エラーは「参照が不正又は不完全です。」となっています。正常に呼び出せるようにするにはどうすればいいですか?

 ★やりたいことは。
  呼出ボタンをクリック→インプットボタン表示 → 呼出番号入力
  呼出番号=シート2B&C列にあるか比較
  有る場合
  入力された番号を最後の番号を除いて指定のセルに分割する
   ↓シート2のデーターをシート1の各セルに呼出す。
       ws.Range("B11").Value = .Cells(lngRow, 4).Value  
       ws.Range("G10").Value = .Cells(lngRow, 5).Value  
       ws.Range("K10").Value = .Cells(lngRow, 9).Value  
       ws.Range("B12").Value = .Cells(lngRow, 10).Value 
 

 シート2
 A3〜データが格納しています。
 シート1
 	[A]	[B]	[C]	[D]	[E]	[F]	[G]	[H]	[I]	[J]	[K]	[L]	[M]	[N]
[7]														
[8]														
[9]														
[10]			1	1			(5列目のデーター)				(9列目のデーター)			
[11]		(4列目のデーター)												
[12]		(10列目のデーター)												

 Set sh = Worksheets("しーと1")

    '呼出番号を入力する
    myR = Application.InputBox(Prompt:="科目番号を入力して下さい 「1112」 の様に", Type:=1)
    'If myR = False Then Exit Sub
    If VarType(myR) = vbBoolean Then
        strPrompt = "マクロがキャンセルされました"
        GoTo Wayout
    End If
       For i = 2 To lngRow
            'データのB列と「科目番号」、C列と「伝票No」を比較して一致したら
            If .Cells(i, "B").Text & .Cells(i, "C").Text = CStr(myR) Then  'vntNumb
                Exit For
            End If
        Next i

     '文字数が3未満若しくは4を超える場合は
    If Len(myR) < 3 Or 4 < Len(myR) Then
        strPrompt = "科目番号入力 " & myR & " が不正なのでマクロを終了します"
        GoTo Wayout
    End If

    '入力した値を分割する
    '★文字数が違うため 例)123 有る場合 ⇒ 12のみ分割し最後の「3」は不要です。
    With sh
        .Range("D10").Value = Right(myR, 1) - 1
        .Range("C10").Value = Mid(myR, 2, 1) - 1
        .Range("B10").Value = Mid(myR, 3, 1) - 1
    End With

    With Sheets("シート2")
        'データの最終行を取得
        '★シート2のデータをシート1に呼び出す。
            lngRow = .Range("A" & Rows.Count).End(xlUp).Row
                ws.Range("B11").Value = .Cells(lngRow, 4).Value  
                ws.Range("G10").Value = .Cells(lngRow, 5).Value  
                ws.Range("K10").Value = .Cells(lngRow, 9).Value  
                ws.Range("B12").Value = .Cells(lngRow, 10).Value 
    End With
Wayout:


 >使用したところエラーが出てしまいうまくいきません

 エラーになったコードはどこか、ちゃんと書いたほうがいいね。
(もし、質問のどこかに書いてあって、こちらが見落としていたらごめん)

 で、
If .Cells(i, "B").Text & .Cells(i, "C").Text = CStr(myR) Then  'vntNumb

 プロパティの前に.(ピリオド)を付けるということは、それ以前に
With 何かのオブジェクト
という With 宣言が必要なんだけど、アップされたコードの上のほうに、その宣言はあるの?

 (ぶらっと)

 (ぶらっと)さん
 ご指摘の所がエラーでた箇所です。

 With
 に入れたところエラーは無くなりましたが、
 相変わらずデーターは全く転記されない状況です。
  ここの部分は「123」とインプットBOXに入れましたが、分割されたデーターは「000」でした、 欲しい結果は「12」ですが、
 その他の転記項目も白紙されたままです。行った何が、だめですか?
 With sh
        .Range("D10").Value = Right(myR, 1) - 1
        .Range("C10").Value = Mid(myR, 2, 1) - 1
        .Range("B10").Value = Mid(myR, 3, 1) - 1
    End With

 Set sh = Worksheets("しーと1")

    '呼出番号を入力する
    myR = Application.InputBox(Prompt:="番号を入力して下さい 「1112」 の様に", Type:=1)
    'If myR = False Then Exit Sub
    If VarType(myR) = vbBoolean Then
        strPrompt = "マクロがキャンセルされました"
        GoTo Wayout
    End If

    '入力した値を分割する
    '文字数が違うため 例)123 有る場合 ⇒ 12のみ分割し最後の「3」は不要です。
    With sh
        .Range("D10").Value = Right(myR, 1) - 1
        .Range("C10").Value = Mid(myR, 2, 1) - 1
        .Range("B10").Value = Mid(myR, 3, 1) - 1
    End With

  With Sheets("しーと2")
       For i = 2 To lngRow
            'データのB列と「科目番号」、C列と「伝票No」を比較して一致したら
            If .Cells(i, "B").Text & .Cells(i, "C").Text = CStr(myR) Then  'vntNumb
                Exit For
            End If
        Next i

     '文字数が4未満若しくは5を超える場合は
    If Len(myR) < 4 Or 5 < Len(myR) Then
        strPrompt = "科目番号入力 " & myR & " が不正なのでマクロを終了します"
        GoTo Wayout
    End If

        'データの最終行を取得
        'シート2のデータをシート1に呼び出す。
            lngRow = .Range("A" & Rows.Count).End(xlUp).Row
                ws.Range("B11").Value = .Cells(lngRow, 4).Value  
                ws.Range("G10").Value = .Cells(lngRow, 5).Value  
                ws.Range("K10").Value = .Cells(lngRow, 9).Value  
                ws.Range("B12").Value = .Cells(lngRow, 10).Value 
    End With
Wayout:


 よくわからないけど、アップされたコードだけを見ると、myR が 123 だとしたら
 Right(myR, 1) - 1 これは 3-1だから 2  ->D列
 Mid(myR, 2, 1) - 1 これは 2-1だから 1 ->C列
 Mid(myR, 3, 1) - 1 これは 3-1だから 2 ->B列

 なので、B,C,D には 2 1 2 と入る。欲しい結果は 1 2 というのもわからないし、実行結果が 0 0 0 というのもわからないなぁ。

 Sub Test()
    Dim myR As Variant
    myR = 123  '実際には格納後のデータ型はDouble型になる
    MsgBox Mid(myR, 3, 1) - 1 & vbLf & Mid(myR, 2, 1) - 1 & vbLf & Right(myR, 1) - 1
 End Sub

 追記)勝手にmyRのデータ型をVariantにしているけど、これがLongやDoubleで規定してあったら
  それはそれで、問題が。キャンセルされても結果(False)は数値の0なのでVarTypeはvbBooleanじゃない。
  なので、コード処理が続行されて、その後のMid関数でエラーになる。

 (ぶらっと)

 多分ですが、言わんとする事はこんなのですか?

 Option Explicit

 Sub 呼出_3()

    Dim i As Long
    Dim lngRow As Long
    Dim sh As Worksheet
    Dim strPrompt As String
    Dim myR As Variant

    Set sh = Worksheets("しーと1")

    '呼出番号を入力する
    myR = Application.InputBox(Prompt:="科目番号を入力して下さい 「1112」 の様に", Type:=1)
    If VarType(myR) = vbBoolean Then
        strPrompt = "マクロがキャンセルされました"
        GoTo Wayout
    End If
    '文字数が3未満若しくは4を超える場合は
    If Len(myR) < 3 Or 4 < Len(myR) Then
        strPrompt = "科目番号入力 " & myR & " が不正なのでマクロを終了します"
        GoTo Wayout
    End If

     '入力した値を分割する
    '★文字数が違うため 例)123 有る場合 ⇒ 12のみ分割し最後の「3」は不要です。
    With sh
        '.Range("D10").Value = Right(myR, 1) - 1
        '.Range("C10").Value = Mid(myR, 2, 1) - 1
        '.Range("B10").Value = Mid(myR, 3, 1) - 1
        .Range("C10").Value = Left(myR, 1)          '★文字列の左から1つ文字を取り出す「123」なら「1」
        .Range("B10").Value = Mid(myR, 2, 1)        '★文字列の左から2つ目の文字を1つ取り出す「123」なら「2」
        .Range("D10").Value = Mid(myR, 3)           '★文字列の左から3つ目から後ろ全てを取り出す「123」なら「3」、「1234」なら「34」
    End With

    With Sheets("シート2")
        '"シート2"のデータの最終行を取得
        lngRow = .Range("A" & Rows.Count).End(xlUp).Row
        'データを先頭(3行目)〜最終迄見て行く
        For i = 3 To lngRow
            'データのB列と「科目番号」、C列と「伝票No」を比較して一致したら
            If .Cells(i, "B").Text & .Cells(i, "C").Text = CStr(myR) Then  'vntNumb
                Exit For
            End If
        Next i
        '比較して一致する物が無かったら
        If i > lngRow Then
            strPrompt = "該当するデータがありません。"
            GoTo Wayout
        End If
        '一致するデータ先頭の行位置を変数lngRowに代入
        lngRow = i
        '★シート2のデータをシート1に呼び出す。
        sh.Range("B11").Value = .Cells(lngRow, 4).Value
        sh.Range("G10").Value = .Cells(lngRow, 5).Value
        sh.Range("K10").Value = .Cells(lngRow, 9).Value
        sh.Range("B12").Value = .Cells(lngRow, 10).Value
    End With

    strPrompt = "処理が完了しました。"

 Wayout:

    Set sh = Nothing

    MsgBox strPrompt, vbInformation

 End Sub

 色々とコードを変更して試して見ているのは、好感が持てますし、努力も好感が持てますが?
 何故コードがこの様な順番に書いて有るのかを善く考えて見て下さいね

 (Bun)


 (ぶらっと)さんすみません。説明不足ですね。

 確かにそうですね^^;「−1」ではなく「−一文字」にするつもりでしたが。。。
 Right(myR, 1) - 1 これは 3-1だから 2  ->D列
 Mid(myR, 2, 1) - 1 これは 2-1だから 1 ->C列
 Mid(myR, 3, 1) - 1 これは 3-1だから 2 ->B列

 「■結果」のようになってほしいだけです。

 しーと1														
	[A]	[B]	[C]	[D]	[E]	[F]	[G]	[H]	[I]	[J]	[K]	[L]	[M]	[N]
[6]														
[7]														
[8]														
[9]	分類	kd	ks	ka		事 業	事 業 名 称				今 回 調 定 額			
[10]														
[11]	内 容													
[12]	納入者													
 ■しーと2 の分類12  NO1 の内容をしーと1に呼び出したい場合
  インプットBOXに「121」と入力

 ■結果

		[B}	[C]	[d}	[E]	[F]	[G]	[H}	[I}	「J]
[2]		分類	NO	内容	事業名所				収入金額	収入者
[3]		12 	1	リンゴ	果物屋				1,000 	許斐
[4]		34 	2	豚肉	肉屋				2,000 	許斐
[5]		56 	3	ドレス	服屋				3,000 	許斐
[6]		789 	4	弁当	弁当屋				4,000 	許斐

 ■例えばシート2の
しーと1														
	[A]	[B]	[C]	[D]	[E]	[F]	[G]	[H]	[I]	[J]	[K]	[L]	[M]	[N]
[6]														
[7]														
[8]														
[9]	分類	kd	ks	ka		事 業	事 業 名 称				今 回 調 定 額			
[10]			1	2			果物屋				\1,000 			
[11]	内 容	リンゴ												
[12]	納入者	許斐												
■しーと2 の分類798  NO4 の内容をしーと1に呼び出したい場合
  インプットBOXに「7984」と入力

 ■結果
しーと1														
	[A]	[B]	[C]	[D]	[E]	[F]	[G]	[H]	[I]	[J]	[K]	[L]	[M]	[N]
[6]														
[7]														
[8]														
[9]	分類	kd	ks	ka		事 業	事 業 名 称				今 回 調 定 額			
[10]		7	8	9			弁当屋				\4,000 			
[11]	内 容	弁当												
[12]	納入者	許斐						

 結果からわかると思いますが、NOは転記しなくていいのです。
 分類だけを分割に転記したいのです。

 (許斐)						


 Bunさん有難うございます。またお世話になります。
 >色々とコードを変更して試して見ているのは、好感が持てますし、努力も好感が持てますが?
 >何故コードがこの様な順番に書いて有るのかを善く考えて見て下さいね
  (T0T)はいがんばります。

 .Range("C10").Value = Left(myR, 1) '★文字列の左から1つ文字を取り出す「123」なら「1」
 .Range("B10").Value = Mid(myR, 2, 1)'★文字列の左から2つ目の文字を1つ取り出す「123」なら「2」
 >.Range("D10").Value = Mid(myR, 3) '★文字列の左から3つ目から後ろ全てを取り出す「123」なら「3」、「1234」なら「34」

 なら.Range("D10").Value = Mid(myR, 3)'★文字列の左から3つ目から後ろ全てを取り出す「123」なら「3」、「1234」なら「3」「4」は転記不要です。

 問題は紛らわしい番号があるために、違ったデーターを呼出してしまうようです。
		[B}	[C]	[d}	[E]	[F]	[G]	[H}	[I}	「J]
[2]		分類	NO	内容	事業所名				収入金額	収入者
[3]		12 	1	リンゴ	果物屋				1,000 	許斐
[4]		34 	2	豚肉	肉屋				2,000 	許斐
[5]		121 	3	ドレス	服屋				3,000 	許斐
[6]		789 	4	弁当	弁当屋				4,000 	許斐
[7]		12 	5	リンゴ	果物屋				1,000 	許斐
 例)3行目のデータを呼びたい時は「121」と入力そうすると「5行目」のデーターが呼出されます。
 もし「12」が複数ある場合インプットBOXに「12」だけを入力するとどちかの内容 が表示させるなら「NO」はインプットする必要ないのですが、
 今のところは、どちらも出来ないので、いろいろ模索しています。

 (許斐)

 コード全体というか、処理の仕様がわからないんだけど、新規ブックに以下のコードを書いて実行してみて。
InputBoxに任意の桁数の数字を入れると、最後の桁をカットして、シートの1行目に残りの数字を1桁ずつ転記する。
こういうことなの?

 Sub test()
    Dim ans As Variant
    Dim v As Variant

    ans = Application.InputBox("入力してくださいね", Type:=1)
    If ans = False Then Exit Sub
    v = Split(Format(Left(ans, Len(ans) - 1), WorksheetFunction.Rept("0-", Len(ans) - 2) & "0"), "-")
    Rows(1).Clear
    With Range("A1").Resize(, UBound(v) + 1)
        .Value = v
        .Value = .Value
    End With

 End Sub

 (ぶらっと)


 >.Range("C10").Value = Left(myR, 1) '★文字列の左から1つ文字を取り出す「123」なら「1」
 >.Range("B10").Value = Mid(myR, 2, 1)'★文字列の左から2つ目の文字を1つ取り出す「123」なら「2」
 >.Range("D10").Value = Mid(myR, 3) '★文字列の左から3つ目から後ろ全てを取り出す「123」なら「3」、「1234」なら「34」
 >
 >
 >なら.Range("D10").Value = Mid(myR, 3)'★文字列の左から3つ目から後ろ全てを取り出す「123」なら「3」、「1234」なら「3」「4」は転記不要です。

 と言う事なら

      '入力した値を分割する
    '★文字数が違うため 例)123 有る場合 ⇒ 12のみ分割し最後の「3」は不要です。
    With sh
        .Range("C10").Value = Left(myR, 1)          '★文字列の左から1つ文字を取り出す「123」なら「1」
        .Range("B10").Value = Mid(myR, 2, 1)        '★文字列の左から2つ目の文字を1つ取り出す「123」なら「2」
        '.Range("D10").Value = Mid(myR, 3)           '★文字列の左から3つ目から後ろ全てを取り出す「123」なら「3」、「1234」なら「34」
        .Range("D10").Value = Mid(myR, 3, 1)        '★文字列の左から3つ目の文字を1つ取り出す「123」なら「3」、「1234」なら「3」
    End With

 とすれば善いのでは?
 VBAのHelpでMid関数(Right関数、Left関数も)を調べて下さい

 >問題は紛らわしい番号があるために、違ったデーターを呼出してしまうようです。
 >		[B}	[C]	[d}	[E]	[F]	[G]	[H}	[I}	「J]
 >[2]		分類	NO	内容	事業所名				収入金額	収入者
 >[3]		12 	1	リンゴ	果物屋				1,000 	許斐
 >[4]		34 	2	豚肉	肉屋				2,000 	許斐
 >[5]		121 	3	ドレス	服屋				3,000 	許斐
 >[6]		789 	4	弁当	弁当屋				4,000 	許斐
 >[7]		12 	5	リンゴ	果物屋				1,000 	許斐
 >例)3行目のデータを呼びたい時は「121」と入力そうすると「5行目」のデーターが呼出されます。

 此れはあり得ないと思いますが?
 コードは、分類(B列)とNO(C列)連結した文字列を、myRを文字列とした値とListの先頭から比較して行き

 「分類(B列) & NO(C列)」= CStr(myR)

 と成った所で、「For〜Next」を抜け出ています
 因って、3行目の値が本当に分類(B列)の値が「12」でNO(C列)が「1」なら引っ掛かると思います?
 増しては、5行目の「12」「5」が引っ掛かるとは思えませんが?
 分類(B列)とNO(C列)の値を善く調べて下さい、何か違う文字が入っていませんか?

 ただ、疑問に思う事は、NO(C列)の数字は必ず1文字なのですか?
 2文字は無いのですか?、空白(Empty値)は無いのですか?
 もし、NO(C列)の値に空白(Empty値)が在る場合、分類(B列)の値が「121」でNO(C列)が「Empty」が
 先に在るなら、そちらが先に引っ掛かりますよ?

 (Bun)

 ぶらっとさんへ

 >Sub Test()
 >   Dim myR As Variant
 >   myR = 123  '実際には格納後のデータ型はDouble型になる
 >   MsgBox Mid(myR, 3, 1) - 1 & vbLf & Mid(myR, 2, 1) - 1 & vbLf & Right(myR, 1) - 1
 >End Sub

 「myR = 123」はDouble型には成らないと思います
 此れは、Integer型に成りと思います
 尚、「myR = 123&」此れならLong型に成りますし、「myR = 123#」ならDouble型に成ると思います

 >追記)勝手にmyRのデータ型をVariantにしているけど、これがLongやDoubleで規定してあったら
 >  それはそれで、問題が。キャンセルされても結果(False)は数値の0なのでVarTypeはvbBooleanじゃない。
 >  なので、コード処理が続行されて、その後のMid関数でエラーになる。

 何を持って「勝手に」と言っているかは解りませんが?
 「データ型をVariantにしているけど」は、私がVariant型を指示していますが?

 「問題が。キャンセルされても結果(False)は数値の0なのでVarTypeはvbBooleanじゃない」
 FalseはBoolean型で「数値の0」では無いと思いますが?(確かにキャストすれば0に成ると思いますが?)
 また、「InputBox メソッドは、[キャンセル] をクリックすると、False を返します。」と私は認識していますので
 戻り値はBoolean型が返ると思っています

 (Bun)


 To Bunさん

 私の表現が拙く、誤解されたようです。申し訳ありません。

 ・Double型の件
   正しくは「数値型」になると書くべきだったですね。VBAが桁数にあわせて、Integer,Long,Doubleに
   自動設定する、これはあたりまえですが、「いわずもがな」のコメントを書いてしまったですね。
   しかも、実際のアップ時、数値桁数を小さくしているので。この場合はIntegerですね。
   かつ、定数でLong型範囲を超えると、123456789012 と打ち込んでも、確かに自動で末尾に#が付加されますね。

 ・「勝手に」Variant型
   何度か書いているように、前スレも読んでいないし、今回の許斐さんの質問のレイアウトもコードも精読していません。
   ましてや、Bunさんのコードやコメントには目を通していません。(これは、これで横着?)
   「勝手に」の意味は、今回の許斐さんのコードでは変数宣言の部分がなかったので、「私が勝手に解釈」したと、そういうことです。

 追記)キャンセル時の件
     これも、私の早とちりでしたね。コードはざらっとみただけでコメントしてますので(偉そうに言うことじゃないですね)
     InputBoxコードの次のコードが目にとまり。でも、今、あらためてよく見ると
     'If myR = False Then Exit Sub
     わゎ!コメントアウトされ、実際には、その下のコード(VarTypeでの判定)だったんですね。
   失礼のてんこもりで、申し訳ありません。

 (ぶらっと)


 To ぶらっとさん

 私も人の上げ足をる様な書き方をして申し訳ありませんでした
 歳を取って気が短く成って来たようです

 (Bun)


 (Bun)さんすみません。ご指摘の通り内容はインプット番号の内容でした。
 ただ、入力値を分割する部分が違う結果でしたので、勘違いしていました。

 >VBAのHelpでMid関数(Right関数、Left関数も)を調べて下さい
  文字を抜き出す関数だと調べました。
  これをいじろうとするのが間違いでした。
  
 IF関数で条件と組み合わせにしてみました。
 しかし、上手くいきません。
 @インプットが「123」と3文字の場合 C10に「1」D10「2」
 A「1234」と4文字の場合 B10に「1」C10「2」D10「3」
 If Len(myR) < 3 < Len(myR) Thenですと@は上手くいくんですが、Aはだめで、
 If Len(myR) < 3 ThenですとAは上手くいくんですが、@はだめで、なかなか悩みます。

 '入力した値を分割する
    With sh
     '数字が3文字未満の場合
      If Len(myR) < 3 < Len(myR) Then
        .Range("C10").Value = Left(myR, 1)          '★文字列の左から1つ文字を取り出す「123」なら「1」
        .Range("D10").Value = Mid(myR, 2, 1)        '★文字列の左から2つ目の文字を1つ取り出す「123」なら「2」
      Else '3文字以上の場合
        .Range("B10").Value = Left(myR, 1)          '★文字列の左から1つ文字を取り出す「1234」なら「1」
        .Range("B10").Value = Mid(myR, 2, 1)        '★文字列の左から2つ目の文字を1つ取り出す「1234」なら「2」
        .Range("D10").Value = Mid(myR, 3, 1)        '★文字列の左から3つ目から後ろ全てを取り出す「1234」なら「3」、「1234」なら「3」
      End If
    End With

 (許斐)

  If Len(myR) < 3 < Len(myR) Then
を3文字以下(4文字未満でも可)にすれば良いのでは


 If Len(myR) < 3 < Len(myR) Then
 これは
 【 Len(myR) < 3 の結果の True 又は False 】< Len(myR)
 と評価されます。 
 (あん)

   >If Len(myR) < 3or4 < Len(myR) Then
  は3文字以下(4文字未満でも可)であって、
  3文字ならA処理
  4文字ならB処理にはできないですよね(??)
 (許斐)
 


 If Len(myR) < 4 Then
や
 If Len(myR) < =3 Then


 有難うございます。
 ようやく思い通りになりました。

 (許斐)

 解決した様だけど、myRは元々数値なのでこんなのでも出来るよ

    '入力した値を分割する
    '@インプットが「123」と3文字の場合 C10に「1」D10「2」
    'A「1234」と4文字の場合 B10に「1」C10「2」D10「3」
    With sh
        If myR \ 1000 = 0 Then
            .Range("B10").Value = Empty
        Else
            .Range("B10").Value = myR \ 1000
        End If
        .Range("C10").Value = (myR \ 100) Mod 10
        .Range("D10").Value = (myR \ 10) Mod 10
    End With

 (Bun)

コメント返信:

[ 一覧(最新更新順) ]


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