Excel (VBA)

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

 
(Windows 10 Home : Excel 2013)
コードのエラーについて
投稿日時: 18/03/15 10:43:52
投稿者: rinahana

いつもお世話になっております。住所録に近い形で仲間の情報をエクセルの表として活用しています。
@とAは現在何のエラーもなく、利用しているコードですが、それを見習ってBとCを@のすぐ下にBを、Aのすぐ下にCを
作って、RUNしたところ「実行時エラー'1004': アプリケーションエラーまたはオブジェクト定義のエラーです。」のアラートが出ます。
なぜなのか?エラーの原因が分かりません。一方は実行できて、一方は出来ないのに苦労しています。
これが出来なくても やや遠回りのロジックでやりたいことはできていますが、分からない事に悩んでいます。
@BのVariant ですが、型が分らないのでVariantとしています。実際はなんでしょうか?
----------------------------------------------------------------------------------
@Dim hyo As Variant
 
Ahyo = Sheets("住所名簿").Range(Cells(2, 1), Cells(iRowEnd + 1, iColCount))
 
 
BDim Circle原簿 As Variant
 
CCircle原簿 = Sheets("住所名簿").Range(Cells(hajime + 1, 1), Cells(owari1 + 1, 13))
----------------------------------------------------------------------------------
 
普段 しっくりいかないのがもう一つあります。ついでに質問ですが、
 
 Sheets("住所名簿").Select
 Range("C8").Select
のように処理の途中や処理終了時に上のようなSelect文を使うのですが、これもエラーがでたり、出なかったりと苦労しています。
この辺のところを教えてもらえれば嬉しいです。
以上 2件についてお願いします。
宜しくお願いします。

回答
投稿日時: 18/03/15 11:11:10
投稿者: めんたん

どちらもRangeオブジェクトです。
 
Dim hyo As Range
Dim Circle原簿 As Range
 
エラーは変数 iRowEnd等の中身が入っていないパターンとシートの指定がうまくいってないことが考えられます。
 
hyo = Sheets("住所名簿").Range(Cells(2, 1), Cells(iRowEnd + 1, iColCount))
 
このとき、仮にシート"hoge"を開いている状態で上記コードを実行すると
 
hyo = Sheets("住所名簿").Range(Sheets("hoge").Cells(2, 1), Sheets("hoge").Cells(iRowEnd + 1, iColCount))
 
とシートの指定がおかしいことになります。
 
With Sheets("住所名簿")
    hyo = .Range(.Cells(2, 1), .Cells(iRowEnd + 1, iColCount))
End With
 
のように書けばいいです。
 
Selectするときは今どのシートがアクティブなのかいつも気にしていないといけませんので、できるだけSelectせずに処理しましょう。
 
Sheets("hoge").Select
Range("A1").Select
Activecell.Value = "hoge"
 

Sheets("hoge").Range("A1").Value = "hoge"
の一文で済みます。

回答
投稿日時: 18/03/15 11:15:12
投稿者: めんたん

なんらかの処理をして最後に見た目の問題で特定のセルを選択したい場合は
 
Application.Goto Sheets("hoge").Range("A1")
 
のようにします。

回答
投稿日時: 18/03/15 11:41:23
投稿者: Suzu

めんたん さんの引用:
どちらもRangeオブジェクトです。

 
めんたんさん。。
 
Rangeではないですよ。Variant が正解です。
 
仮に、Range なのであれば、
 
Dim hyo As Range
hyo = Sheets("住所名簿").Range(Cells(2, 1), Cells(iRowEnd + 1, iColCount))
 
これが実行できるはずですが、エラーになりますよね。 (Setが必要)
 
 
引用:
Sheets("住所名簿").Range(Cells(2, 1), Cells(iRowEnd + 1, iColCount))

 
これで指定されているのは、Rangeオブジェクトですが、
左側に、「hyo =」が入っている事で代入という事になります。
 
このとき、Rangeオブジェクトの既定プロパティが、Value になっていますので、
左側の変数 hyo に Value が渡されます。
 
で・・・このValue ですが、数値でも、文字列でもなく、あくまでも Variant です。
Empty がありますから。。

回答
投稿日時: 18/03/15 11:44:54
投稿者: めんたん

おっと、Set がなかったのを見逃してました!
失礼しました。たんに値を取り込んでるだけですね。

回答
投稿日時: 18/03/15 11:52:36
投稿者: めんたん

 rinahanaさん、思い込みで範囲指定のRangeオブジェクトとして回答してしまい失礼しました。
 
ですが、シート指定がおかしい、変数hajime等の中身が入っているか、Selectしない、という点には変わりありませんのでその点を考慮してみてくださいませ。
 

投稿日時: 18/03/15 12:23:32
投稿者: rinahana

めんたん さん、Suzu さん 
早速の回答をありがとうございます。
指定の通りの事に気を付けて、コードを作成してみます。
実のところ 型についてMS-DOS BASICの変数の型 程度は十分理解しているつもりですが、VBAになってから、色々の方の変数宣言が出てきて
十分な理解が出来ていないのが現実です。メモリの心配がなくなった時代ですから、ほとんどLong、String,Variantで済ましています。
ところで、
hyo = Sheets("住所名簿").Range(Cells(2, 1), Cells(iRowEnd + 1, iColCount))

Set hyo = Sheets("住所名簿").Range(Cells(2, 1), Cells(iRowEnd + 1, iColCount))
との違いはと 
hyo がエクセルのセルの実態を投射しているのかが不確実で使用しています。
自分ではまるで2次元テーブルの様に利用していますが、それでいいのですかねぇ。
 
色々とありがとうございました。

回答
投稿日時: 18/03/15 13:12:19
投稿者: めんたん

Setが付いてない場合は、変数に値、文字列、配列などの値を代入しています。
Set 変数 = 値とする時には、オブジェクトを入れるオブジェクト型変数です
 
Dim myRange As Range
Set myRange = Sheets("hoge").Range("A10:A15")
 
とRangeオブジェクトを代入した場合、プロパティを参照できるので
 
With myRange.Cells(2,1)
    '値を入力したり
    .Value = "ここはA11セル"
    '背景色を変えたり
    .Interior.ColorIndex = 3
    'フォントを操作したり
    .Font.Bold = True
End With
 
など操作できますが、値や配列などが代入されているときはそのような操作はできません。

投稿日時: 18/03/15 13:54:53
投稿者: rinahana

めんたん さん
ありがとうございます。
お陰で、モヤモヤ として、”適当に出来た”で処理をしていたことが、まだ十分とはいきませんが ナントかモヤモヤがすっきりした感じです。
ありがとうございます。
今後とも宜しくお願いします。