[[20091128111355]] 『アプリケーション定義またはオブジェクト定義のエ』(hikomitsu) ページの最後に飛ぶ

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

 

『アプリケーション定義またはオブジェクト定義のエラー』(hikomitsu)

Excel VBA を初めて作成します。Excel2007でExcel2003の互換で作成しています。
集計結果をセルに書き込み時、「errno1004:アプリケーション定義またはオブジェクト定義のエラー」が出ます。解決方法を教えてください。概要は以下の通りです。

  
  Sub calc_total(ByVal strsheetNM As String) 
 
  Dim j                As Integer
  Dim curtotalmeal     As Currency
  
  <curtotalmeal に集計しています>
  curtotalmeal = curtotalmeal + curwk
 
  <集計したcurtotalmeal をセルにセットする時上記のエラーがでます>
  Worksheets(strsheetNM).Range(j, AD).Value = curtotalmeal

  セットするセルの書式設定の表示形式は「数値型」になっています。

  よろしくお願いします。


 > Range(j, AD).Value
         ^^^^^
 AD は列Indexですか?
 Cells(j, "AD") のこと?

 j は Long型にしておいた方がよいのでは?
 (seiya)


 >Range(j, AD)
Rangeオブジェクトの取得は「名前による取得」もしくは、
「二つのRangeオブジェクトによる矩形範囲の取得」が一般的です。
変数jは宣言されていますが、「数値型変数」です。
変数ADは未定義の変数です。
Cells(j,AD)という書き方との勘違いではありませんか?
(みやほりん)(-_∂)b

 早々のご回答ありがとうございます。

 私の勉強不足で、jは、行インデックスデでADは固定の列番号です。
 Cells(j, "AD") にしたらエラーは無くなりました。
 しかし、行ごとに計算してcells(J, "AD")に値をセットしたいのですが、3行目しか値 が入りません。
 以下のようにしています。どうしたらいいか助言をお願いします。

  For j = 3 To 40 Step 2
     For i = 0 To 8
      curtotalmeal = curtotalmeal + curwk
    Next i
     Worksheets(strsheetNM).Cells(j, "AD").Value = curtotalmeal
   Next j


     [A]    [B]    [C]     [D] ・・・・[AD]
 [1]
 [2]
 [3]
 [4]
 こんなデータがあって、
 このコードを動かすと
 こんな結果になるけど
 こうしたい。

 と、サンプルデータ・コピペで動かせるコード・希望結果
 をセットで載せて説明されると良いと思います。

 (HANA)

 了解です。
     [A]    [B]    [C]    [D] ・・・・[AD]
 [3] 2000  3000   5000   4000         14000   (3,AD)には合計 14000が計算されますが、以下
 [5] 1000  2000   3000   4000         (5,AD),(7,AD)・・・に表示されず、
 [7]                      j の値が 3 のままなのですが、     
 [9]                     For j = 3 To 40 Step 2 でいいと思うのですが? 
 [11]                     よろしくお願いします。 
  ・
 ・
 [40]
  ↑
  j

 「コピペで動かせるコード」も載せましょう。

 上で載せて居られるコードは、
 Sub や End Sub も無いですし
 いきなり「strsheetNM」「curwk」等があるので
 コピペじゃ動きません。

 strsheetNMは、「Sub calc_total(ByVal strsheetNM As String)」
 って事だとして・・・また
 curwkにデータを入れる行が有ったとしても
 curtotalmealをリセットして次の行に移らないと
 累計になってしまうと思います。
 「希望結果」がないので、それで良いのか
 駄目なのか、判断が付けられませんが。。。

 (HANA)

 内側のループの問題は考えないとしても、3行目だけにしか表示されないのは
 どうしてでしょう?

 ループの必要は無いと思いますが?

 With Worksheets(strsheetNM).Cells(3, "AD")
     With .Resize(2)
         .FormulaR1C1 = [{=sum(rc1:rc4);=""}]
         .AutoFill .Resize(37)
     End With
     .Resize(37).Value = .Resize(37).Value
 End With
 (seiya)

  再度提示します。 
     区分 金額  区分 金額 ・・・  集計エリア 
      5      6      7      8           
     [E]    [F]    [G]    [H] ・・・・ [AD]
 [3]       10000          10000       50000 (3,AD)には区分によって集計して 50000が計算される
 [5]       10000          10000    ????? 同様に (5,AD),(7,AD)・・・にも計算されるはず
 [7]    10000      10000    ?????  j の値を表示したら 3 のままで集計されない    
 [9]    10000          10000       ?????  For j = 3 To 40 Step 2 でいいと思うのですが? 
 [11]   10000          10000       ?????  ?????が計算されない? 
  ・                     区分(21),金額(22)から前に集計していき、
 ・                                         区分=2,3ならその行は前は集計しないで次行へ
 [40]                                        というような処理です。
  ↑
  j
 
 VBA はほぼ以下の通りです。
 '*******************************************
 '集金合計
 '*******************************************
 Sub calc_total(ByVal strsheetNM As String)
     Dim i                As Integer
     Dim j                As Integer
     Dim strkbn           As String
     Dim curwk            As Currency
     Dim introw           As Integer
     Dim intcolkbn        As Integer
     Dim intcolkin        As Integer
     Dim curtotalmeal     As Currency       '金額合計

 On Error GoTo calc_total_err

    '初期化
    curtotalmeal = 0
    introw = 3         '行
     'intcolkbn = 21     '区分の列インデックス(1月)
     'intcolkin = 22     '金額の列インデックス(1月)
    '3行から1行おきに集計
    For j = 3 To 40 Step 2
        intcolkbn = 21     '区分の列インデックス(1月)
        intcolkin = 22     '金額の列インデックス(1月)

        '1月→4月
        For i = 0 To 8
            '区分
             strkbn = CStr(Worksheets(strsheetNM).Cells.Item(j, intcolkbn).Value)
            '金額
            Select Case strkbn
                Case "", "2", "6"     '区分=SP、2、6の時5,000
                    curwk = 5000
                Case "5"              '区分=5の時10,000
                    curwk = 10000
                Case Else
                    curwk = 0
            End Select

            '集計
            curtotalmeal = curtotalmeal + curwk

            '区分2,3の時はそれ以前は集計しない
            If strkbn = "2" Or strkbn = "3" Then
               Exit For
            End If

            '前へ
            intcolkbn = intcolkbn - 2
            intcolkin = intcolkin - 2
        Next i

        '表示
        '----
        MsgBox "curtotalmeal=" + CStr(curtotalmeal) + "j=" + CStr(j)
        '合計
        Worksheets(strsheetNM).Cells(j, "AD").Value = curtotalmeal
        curtotalmeal = 0
   Next j

   Exit Sub
 calc_total_err:
    MsgBox "errno" & Err.Number & ":" & Err.Description & vbcrlf & " ヘルプ " & Err.HelpContext
  'HelpContext

 End Sub


 途中で何らかのエラーが起きていて、
 On Error GoTo calc_total_err
でエラートラップまで処理が飛んでしまう、と言うことではないとすれば・・・?
 
>j の値を表示したら 3 のままで集計されない
ループはするけど、変数jは3のまま、と言うニュアンスにとれますが、
そんなことが起きているとすると、ループ処理が信頼できなくなっちゃいますね。
 
【推測】
(1)WorkSheet_Changeイベントプロシージャでcalc_totalが呼び出される。
(2)MsgBox "curtotalmeal=" + CStr(curtotalmeal) + "j=" + CStr(j) でメッセージ表示
(3)Worksheets(strsheetNM).Cells(j, "AD").Value = curtotalmeal で
   セルの値が変更される。
(4)(3)の結果、(1)〜(3)が繰り返される。
   このとき、全ての再帰呼出プロセスが 変数j=3の時点で繰り返される為、
   > j の値を表示したら 3 のままで集計されない    
   のように「感じる」。
(5)そのうち、オーバーフローしてとまる。
 
これはブレークポイントを設けてステップインデバッグしないと気が付きません。
(みやほりん)(-_∂)b

 (みやほりん)(-_∂)b さん 大正解です。 ありがとうございます。
 なんか原因がわかったような気がします。
 いままでの質問にはあげていなかったのですが、Excel Objects で以下の記述をしていました。 
 Private Sub worksheet_activate()
    Call calc_total("A")
 End Sub
 Private Sub worksheet_change(ByVal target As Excel.Range)
    Call calc_total("A")
 End Sub
 そのため、3行目が書き換わった時点で、再度calc_total("A")が起動されていたようです。
 後半の3行をコメントにしてみたら、最後まで集計されて値が表示されました。  
 ただし、最初に開いた時のみCALLされるので、ボタンかフォームにCALLを割り当てて実行するように 
 しようと思っています。
 (みやほりん)(-_∂)b さん、(seiya)さん、(HANA)さん 本当にありがとうございました。


 Private Sub worksheet_change(ByVal target As Excel.Range)
    Application.EnableEvents = False
    Call calc_total("A")
    Application.EnableEvents = True
 End Sub
 
このようなコードでもイベントマクロの再起呼び出しを防げます。
 (みやほりん)(-_∂)b

 ありがとうございました。
 もうひとつ質問ですが、別の項目を集計しようとしたら、「errno13型が一致しません」が出ます。
 '←??? の箇所でエラーになっていると想われます。
 教えていただけないでしょうか?

 '*******************************************
 '集金合計
 '*******************************************
 Sub kyu_syu_total(ByVal strsheetNM As String)
    Dim i                As Integer       '横(月)のインデックス
    Dim j                As Integer       '縦(番号)のインデックス
    Dim strkbn           As String        '区分エリア
    Dim strsei           As String        '性別エリア
    Dim curwk            As Currency      '月の金額の作業エリア
    Dim intcolkbn        As Integer       '横(月)の区分のインデックス
    Dim intcolkin        As Integer       '横(月)の金額のインデックス
    Dim curtotalmeal     As Currency       '各番号の集金合計

 On Error GoTo calc_total_err

    '初期化
    curtotalmeal = 0
    '1番→40番
    For j = 3 To 81 Step 2
        strsei = CStr(Worksheets(strsheetNM).Cells.Item(j, "d").Value)
        If strsei = "1" Or strsei = "2" Then
            intcolkbn = 21     '区分の列インデックス(2月調整〜4月)
            intcolkin = 22     '集金額の列インデックス(2月調整〜4月)

            '2月→4月
            For i = 0 To 8
                 '区分
                strkbn = CStr(Worksheets(strsheetNM).Cells.Item(j, intcolkbn).Value)
                '金額
                Select Case strkbn
                    Case "5", "6"    
                      curwk = CCur(Worksheets(strsheetNM).Cells.Item(j, i).Value)  '←???
                    Case ""              
                      curwk = CStr(Worksheets(strsheetNM).Cells.Item(j, i).Value) / 2
                     Case Else
                        curwk = 0
                End Select

                '集計
                curtotalmeal = curtotalmeal + curwk

                'それ以前の月は集計しない
                If strkbn = "2" Or strkbn = "3" Then
                   Exit For '
                End If

                '前の月へ
                intcolkbn = intcolkbn - 2
                intcolkin = intcolkin - 2
            Next i

            '表示
            '----
            'MsgBox "curtotalmeal=" + CStr(curtotalmeal) + "j=" + CStr(j)
            '集金合計
            Worksheets(strsheetNM).Cells(j, "Z").Value = curtotalmeal
            curtotalmeal = 0
        End If
   Next j

   Exit Sub
 calc_total_err:
    MsgBox "errno" & Err.Number & ":" & Err.Description & vbcrlf & " ヘルプ " & Err.HelpContext
 'HelpContext

 End Sub


 >'←??? の箇所でエラーになっていると想われます。
[hikomitsu]さんのブックが手元にあるわけではないので、ご自身でデバッグして
頂かないと、何が原因かは特定できません。
【推測】
エラー13、型が一致しない = 通貨型変数curwk に値が代入できない、という
ことだと思われるので、[Worksheets(strsheetNM).Cells.Item(j, i).Value]が
数値に変換できない値である可能性があります。
エラーが起きる時点での、[Worksheets(strsheetNM).Cells.Item(j, i).Value]を
ウォッチ式、各変数の状況をローカルウィンドウで確認して、原因を特定してくだ
さい。
 
と、思ったの で す が、
 
コードを見る限りでは、i=0の時の Cells.Item(j, i) が取得できないのではないかと
思われます。Cells.Item(1,1)がA1セルにあたるので、i=0は取得可能な範囲外となり、
Rangeオブジェクトは取得できず、ご提示の「エラー13」ではなくて、「エラー1004 
アプリケーション定義、またはオブジェクト定義エラー」が起きるべき部分であると
判断します。
i=0の時、Case Elseに分岐して、i=1以降のループであれば、「エラー13」の可能性も
ありますが、ご提示のコードではこれも考えにくい。
 
なぜなら・・・
strkbnは For i = 0 To 8 のループ内で取得していますが、変数iに影響されないので、
i=0-8の1ループ内ではSelect Case の分岐は常に同じであるはずです。ご提示のコード
では i=0 のループだけがCase Elseに分岐することは考えにくいので、i=0のときでも、
Case "5", "6" の部分のステートメントは実行されるはずです。
したがって、次のように判断できます。
・ご提示のコードが実際のものとは違う。
・エラーの控え違い。
 
相変わらず、理屈っぽいコメントですが、許されたし。
(みやほりん)(-_∂)b


 (みやほりん)(-_∂)さん するどいご指摘でした。
 全くその通りで、i=0の時の Cells.Item(j, i)
 が間違いで、Cells.Item(j, intcolkin) が正解でした。 
 いつも適格なコメントをいただき感謝しています。  


 型が一致しないのは変数と変数に代入する値の型が一致しないと言うことです。
ブレークポイントを設けてデバッグしてください。
みやほりん

コメント返信:

[ 一覧(最新更新順) ]


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