Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Home : Excel 2013)
rangeメソッドは失敗しました。globalオブジェクトエラー
投稿日時: 20/07/26 23:45:33
投稿者: ぜんだまん
メールを送信

これはなんで「1004実行時エラー、rangeメソッドは失敗しました。globalオブジェクト」
のMSGで止まるのでしょうか
またこういったエラーはどういう風に調べて解決していきばいいのでしょうか
よろしくお願いします。
 
Sub 合否判定()
 
    Dim i As Long
    Dim p As Range
    Set p = Range("A" & i).Value '停止部分、cellsに変えてみたが同じ
     
    For i = 1 To 5
     
        If p < 80 Then
            Range("B" & i).Value = "不合格"
         
        Else
            Range("B" & i).Value = "合格"
     
        End If
    Next i
     
    MsgBox "合否判定終了しました"
 
End Sub

回答
投稿日時: 20/07/26 23:50:23
投稿者: simple

Set p = Range("A" & i).Value
 
Range("A" & i).Valueはセルの値なので、文字列か数値か知らないが、
いずれにせよ、それはRangeオブジェクトではないから、
Range変数に代入することは不可能です。
 
オブジェクトとは何かという基本をしっかり理解することが先決です。
手元にテキスト(VBA学習用の教科書、参考書等)は置いてないのですか?

回答
投稿日時: 20/07/27 00:03:54
投稿者: simple

それ以前にA0セルという指定でエラーになっていますね。

回答
投稿日時: 20/07/27 06:51:13
投稿者: simple

どのように調べるか、
エラーになった段階で関連する変数の値を調べます。
ローカルウインドウの使い方や、
変数名にカーソルを当ててポップアップさせる方法を
調べてください。
それがゼロの時何が起こるか考えてください。

回答
投稿日時: 20/07/27 08:23:15
投稿者: WinArrow
投稿者のウェブサイトに移動

エラーの原因は、simpleさんのご指摘通りですが、
  
コードを全体的にみますと
 セルA1〜A5の値を判定して、80未満の場合、"不合格"を対応するB列セルに格納する
という仕様に思われます。
 
このような仕様を前提にすると
> Dim p As Range

Dim p As Long
に修正し、
> Set p = Range("A" & i).Value '停止部分、cellsに変えてみたが同じ

    p = Range("A" & i).Value
に修正したほうがよいでしょう。
但し、セルA0は存在しないので正しく修正してください。
でも・・・
> If p < 80 Then
この判定は、意図したものと違うように思います。
 例えば
pが50だったら、全てが「不合格」になってしまいます。
A1〜A5まえループしているが、その値は、使われていませんね?
 
コード全般を見直ししたほうがよいでしょう。

回答
投稿日時: 20/07/27 11:46:08
投稿者: WinArrow
投稿者のウェブサイトに移動

推測ですが、
多分、命令は間違っていますが
> Set p = Range("A" & i).Value
が、For ループの外に記述されていることが、問題の発端ではないでしょうか?
 
 
以下のように修正すれば、意図した通りになるのではないでしょうか?
 
Sub 合否判定()
   
     Dim i As Long
     Dim p As Long
      
     For i = 1 To 5
p = Range("A" & i).Value
If p < 80 Then
             Range("B" & i).Value = "不合格"
           
         Else
             Range("B" & i).Value = "合格"
       
         End If
     Next i
       
     MsgBox "合否判定終了しました"
   
End Sub
 
 

回答
投稿日時: 20/07/27 14:00:18
投稿者: simple

いくつかの質問に接しました。
お勧めしたいのは、薄くて結構なので
入門書を一度通して学習することです。
 
そこに載っている基本的な例文を、
ご自分でキーインし、ステップ実行してみてください。
一行一行の意味を考えたり、基本的なイディオムを
仕入れる必要があると思います。
一つ一つご自分で作っていくのも結構ですが、
知識の乏しい状態で試行錯誤しても効率が悪い気がします。
 
譬えて言えば、
英文解釈に慣れていない方が
英作文から学習している感じです。
ある程度英語に触れることが無ければ
英作文もままならないと思います。
 
今後とも質問はいつでも歓迎しますが、
上記の観点も少し考えられてはいかがですか?

回答
投稿日時: 20/07/27 15:47:33
投稿者: Suzu

simpleさんや WinArrowさん とだいぶ被るのですが・・・
 
エラーが発生した場合には、
VBE画面で、カーソルを 処理内の オブジェクト等を持っていくと
その 中身を 見ることができます。
 
今回は、右辺の Range("A" & i).Value の
 Range の上へ持っていくと 「Rangeオブジェクトは失敗しました〜〜」 となっているはずです。
 
じゃぁ、何が問題と考えたときに i の上へ持っていくと i の中身が「0」 と表示されます。
 
ここで、A0 セルって無いよな? と気づければ良いのですが、気づけない場合には
イミディエイトウィンド にて
?Range("A0").Value を 入力し Enter をすると 「オブジェクト定義」エラー表示になります
 
さらに 余計な Value を外し
?Range("A0") も 同じエラー ここまでくれば、 「"A0" ってセル無い」と気づけるかと思います。
 
 
その上で、i が 0 となっているのは どうしてなんだろう? 解決は?
と考えたとき 処理フローと構文が理解できていないと解決できません。
 
エラー解消為には ※※ の位置に 代入する処理を持っていく事になりますが
そこでも、オブジェクト変数に値を代入する事になるので
再び エラーになる ので。。 Value を外す
 
という順番で解決します。
 
カーソルを当てても判断がつかない場合 (主にはオブジェクト変数の確認)
には、ローカルウィンドを表示させオブジェクト変数の中身を確認
 
となります。
 
 
実際にVBE画面でコードを記述する前に どんな動作をさせたいのか、
プログラム フロー をイメージできた方が良いです。
 
その為に、他の方の作った コードに
「日本語でコメントを入れてみる」事が 勉強になると思います。
 
 

Sub 合否判定()

  Dim i As Long   '長整数変数
  Dim p As Range  'Range オブジェクト変数

  ' Rangeオブジェクト変数 p に A列 の i行目 の セルの値 を代入
  '' 【問題点】この段階で、i は 0 なので、「A0」というセルは無く
  '' 【問題点】オブジェクト変数 に、オブジェクトでない物を代入しようとしている
  Set p = Range("A" & i).Value '停止部分、cellsに変えてみたが同じ

  '変数 i を 「1」から「5」まで 繰り返す
  For i = 1 To 5

'※※

    ' オブジェクト変数 p が 80未満か判定
    ' オブジェクト変数 p の Rangeオブジェクト の 規定のプロパティーがValue になるので
    ' Value が 80未満か判定する事になる
    If p < 80 Then
      ' 80未満のとき
      ' B列 i行目 のセル に 不合格 を代入
      Range("B" & i).Value = "不合格"

    Else
      ' B列 i行目 のセル に 合格 を代入
      Range("B" & i).Value = "合格"

    End If
  Next i

    MsgBox "合否判定終了しました"

End Sub

回答
投稿日時: 20/07/27 16:45:15
投稿者: WinArrow
投稿者のウェブサイトに移動

別の観点で一言
 
今回の要件は
A列セルの値を条件判定で、隣のB列セルに"合格","不合格"を入れる
という仕様です。
条件
80未満は、"不合格"、80以上は"合格"とします。
 
VBAでなく、数式で充分に対応できます。
B1セルに
=IF(A1<80,"不合格","合格")
を入力し、下へフィルドラッグします。
 
処理時間的には、ほとんど同じですが、
VBAで対応しなければいけない案件ではありません。
VBAの勉強ということならば、
コード記述から入るのではなく、
オブジェクト、プオパティ、メソッドなど
VBAの基本的なことを理解しないまま、
コードに走ると混乱すうと思います。
 
今回のエラーメッセージとエラーの内容が直感的に整合しないから、
初心者には、難しいと思います。
 

投稿日時: 20/07/28 19:25:27
投稿者: ぜんだまん
メールを送信

simple さんの引用:
Set p = Range("A" & i).Value
 
Range("A" & i).Valueはセルの値なので、文字列か数値か知らないが、
いずれにせよ、それはRangeオブジェクトではないから、
Range変数に代入することは不可能です。
 
オブジェクトとは何かという基本をしっかり理解することが先決です。
手元にテキスト(VBA学習用の教科書、参考書等)は置いてないのですか?

 
仰る通り基礎がなっておりませんでした。
基礎に帰って少しハードルを下げて取り組みます。

投稿日時: 20/07/28 19:29:07
投稿者: ぜんだまん
メールを送信

simple さんの引用:
それ以前にA0セルという指定でエラーになっていますね。

 
Forの内側に入れなければならなかったようで、気が付きませんでした。
さっそく"いちばんやさしいExcel VBAの教本"を買ってきました。

投稿日時: 20/07/28 19:31:54
投稿者: ぜんだまん
メールを送信

simple さんの引用:
どのように調べるか、
エラーになった段階で関連する変数の値を調べます。
ローカルウインドウの使い方や、
変数名にカーソルを当ててポップアップさせる方法を
調べてください。
それがゼロの時何が起こるか考えてください。

 
エクセルの神髄というサイトでローカルウィンドウについて勉強します。

投稿日時: 20/07/28 19:32:58
投稿者: ぜんだまん
メールを送信

WinArrow さんの引用:
エラーの原因は、simpleさんのご指摘通りですが、
  
コードを全体的にみますと
 セルA1〜A5の値を判定して、80未満の場合、"不合格"を対応するB列セルに格納する
という仕様に思われます。
 
このような仕様を前提にすると
> Dim p As Range

Dim p As Long
に修正し、
> Set p = Range("A" & i).Value '停止部分、cellsに変えてみたが同じ

    p = Range("A" & i).Value
に修正したほうがよいでしょう。
但し、セルA0は存在しないので正しく修正してください。
でも・・・
> If p < 80 Then
この判定は、意図したものと違うように思います。
 例えば
pが50だったら、全てが「不合格」になってしまいます。
A1〜A5まえループしているが、その値は、使われていませんね?
 
コード全般を見直ししたほうがよいでしょう。

 
ご指摘の箇所を修正したらあっさり動きました。ありがとうございました。