質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

3173閲覧

Excel VBAの繰り返し文に出るエラー

iemon-yasu

総合スコア18

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2016/08/10 01:17

編集2016/08/10 02:27

###前提・実現したいこと
VBA初心者です。昨日始めました。
現在ExcelVBAを用いて、繰り返し文を書いています。
飛行機の最適な乗継便を探すプログラムを作ることが目的です。

###発生している問題・エラーメッセージ
①『オブジェクト変数またはWithブロック変数が設定されていません』
②『型が違います』

###該当のソースコード

Sub

1 Dim InputRow As Range 2 3 Worksheets("整合性確認").Activate 4 ActiveSheet.Cells.Select 5 6 InputRow = "InputRow,1" 7 8 9 Worksheets("整合性確認②").Activate 10 ActiveSheet.Cells.Select 11 Selection.EntireColumn.Hidden = False 12 13 For Each InputRow In Range("A1:A104876") 14 InputRow = InputRow + 1 15 Next InputRow 16End Sub``` 17 18 19###試したこと 20課題に対してアプローチしたことを記載してください 21②の課題に対して、 22変数の型を、Integer/long/string/variantなど試しましたが、 23どれを用いてもダメでした。 24 25###補足情報(言語/FW/ツール等のバージョンなど) 26より詳細な情報

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jawa

2016/08/10 01:56

ソースコードを提示する場合、本文中にそのまま記述するとネストの段組みなどが崩れて読みにくくなってしまいます。 コードの前後を```で括ってもらえると見やすくなりますのでお願いします。
jawa

2016/08/10 02:20

すみません、さっそく修正いただきましたが'''ではなく```です。 普段使わない記号でわかりにくいですよね。 あと1行毎ではなくソース全体を括ればOKです。(ソース前後の行を```にする) わかりにくければ、質問文中のソース部分を範囲選択して</>ボタンを押すと```で括ってくれます。
jawa

2016/08/10 03:58

質問者さんの画面ではきれいに見えているのでしょうか? 私の画面では修正していただくたびにひどくなっていr・・・。 お願いした操作を行うことが目標地点ではなく、見やすくなることが目標地点なのです(T-T) 一度、今記述しているソース部分をきれいに消してから、ソースを貼り付けなおし、</>ボタンを使い```で括ってみてくださいm(__)m
guest

回答3

0

InputRowという変数の使われ方が変です。

(1)

Dim InputRow As Range

と宣言されているので、InputRowの型はRange

(2)

InputRow = "InputRow,1"

文字列を代入しようとしているので、InputRowの型はStringsだと考えているのでしょうが、Range型なので『型が違います』というエラーになります。

(3)

InputRow = InputRow + 1

1を加算しているので、InputRowの型はIntegerかLongと考えているのでしょう。

質問のコードで使われているInputRowは、本来3つの異なる変数であるべきなのではないでしょうか。
何をしようとしているのかを整理して、コードの見直しをしては如何でしょうか。

投稿2016/08/10 01:39

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iemon-yasu

2016/08/10 02:12

なるほど! 参考にしたサイトさんの場合は、 Dim InputRow As Range となっていたので、そのまま点予王してしまいましたが、これがエラーの原因になっていたのですね! プログラム初心者なので、まだまだ勉強しながらですが、見なおしてみます!
coco_bauer

2016/08/10 02:27

Dim文だけを修正してもダメです。本来別々の変数にすべきところが、みんなInputRangeになっている事が問題なのです。まず、何をするコードを作ろうとしてるのかを考えてください。そして、それぞれの用途に合わせて変数を定義してください。今のコードをエラーが出ないように出来たとしても、意味のある機能を発揮する事はないでしょう。
guest

0

ベストアンサー

回答が長くなってしまうので、別枠で立てさせていただきます。

やりたいことを整理してみましょう

たぶん、まだ目的の機能を作る段階の本当に入り口の部分なのですね。

・SEG1の路線に対し、SEG2から最適な路線を持ってくる
・1行のSEG1に対して2行のSEG2を取得する
・1行ずつずらしてSEG2と対応させる

ここらへんはまだ何もできていないですよね?

いきなり最終形を目指すと、やらなければならないことが多すぎて目的を見失い、迷走してしまいます。

やらなければならないことを整理して、ひとつづつ解決していきましょう。

いまやらなければならないことは、
①整合性確認シートからSEG1の情報を順に取り出すループ処理の作成
②取得したSEG1に対応する最適なSEG2の組み合わせを取得する処理
③結果を整合性確認2シートに出力する処理
でしょうか。


①は今あるループ処理が使えそうです。
整合性確認シートのA列全体でよければ、現在のコードや
For Each InputRow In Worksheets("整合性確認").Range("A:A")
という記述でよいですが、
For Each InputRow In Worksheets("整合性確認").Range(Range("A1"), Cells(Rows.Count, 1).End(xlUp))
のようにデータの存在する範囲だけループする方がスマートです。

上記のRange(Range("A1"), Cells(Rows.Count, 1).End(xlUp))という部分は、「A列1行目からA列の最終データ行まで」というRange(範囲)になります。


②については、「最適」の判断が分からないことにはプログラム化はできません。


③は前回の出力行を覚えておいて、続きに出力するような方法でいいでしょう。


以上をまとめると以下のような感じになります。

Sub check4() Dim iOutRow As Integer '出力行番号 Dim shtI As Worksheet '入力シート Dim shtO As Worksheet '出力シート Set shtI = Worksheets("整合性確認") Set shtO = Worksheets("整合性確認②") Dim rngSeg1 As Range 'SEG1の便名セル Dim rngSeg2_A As Range 'SEG2の便名セル① Dim rngSeg2_B As Range 'SEG2の便名セル② '最初の出力行は1行目 iOutRow = 1 '①「整合性確認シート」のA列に存在するセルを1つづつ取り出すループ処理 For Each rngSeg1 In shtI.Range(Cells(1, 1), Cells(Rows.Count, 1).End(xlUp)) '取り出したセル(SEG1の便名)を表示(確認用) MsgBox rngSeg1.Value '②SEG1の路線に対し最適なSEG2を2つ取得。(条件不明のため暫定処置) Set rngSeg2_A = shtI.Range("F1") Set rngSeg2_B = shtI.Range("F2") '③取得結果を「整合性確認2シート」に出力 shtO.Cells(iOutRow, 1) = rngSeg1.Value '出力シートのA列にSEG1便名を出力 shtO.Cells(iOutRow, 2) = rngSeg2_A.Value '出力シートのB列にSEG2便名①を出力 shtO.Cells(iOutRow, 3) = rngSeg2_B.Value '出力シートのC列にSEG2便名②を出力 '出力行番号を +1 する(次回の出力行番号となる) iOutRow = iOutRow + 1 Next rngSeg1 End Sub

実際の目的としている動作とは違うかもしれませんが、コーディングのサンプルとして記載しました。
参考になれば幸いです。
がんばってみてください。

投稿2016/08/10 05:07

jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iemon-yasu

2016/08/10 05:43

ありがとうございます! 拙い説明の中で、私がどんなことをやりたいのか、 どんな状況にいるのかなど、推測したうえでアドバイズをいただき、 今後どう進めていけば、解決の糸口が見えてくるのかといった 筋道を立てていただいたことから、ベストアンサーとさせていただきました! jawaさんのアドバイスを参考に、条件も考えて進めていこうと思います。 まだまだ始めてばかりで未熟ですが、いずれは私も困っている人にアドバイスできるようになりたいと思います。
guest

0

お願い

作りたいものの全体像と、記述した処理はわかりましたが、提示いただいたコードがその中でどんな役割を目的としているのかに結びついていません。
check4関数がどんなデータをもとに、どんな結果を期待するものなのかについて説明が不足しています。

処理前の状態と、処理後にどうなってほしいのか、提示いただけると助かります。

・"整合性確認"シートの内容
・"整合性確認②"シートの内容(特にA列)
・InputRowに入る内容
・InputRow = "InputRow,1"に期待する動作
・InputRow = InputRow + 1に期待する動作(対象セルの値を+1する動作でよい?)
あたりの説明があるとアドバイスしやすいです。

よろしくお願いします。

エラーについて

>①『オブジェクト変数またはWithブロック変数が設定されていません』
>②『型が違います』
エラー発生個所の記載がありませんが、いずれも
InputRow = "InputRow,1"
の部分でのエラーではないでしょうか?

おそらく本質的には①②とも同じで、変数の使い方を間違えているのだと思います。

①Range型で宣言したInputRow変数にオブジェクト(セルやレンジ)を割り当てる前に"InputRow,1"という文字列を格納しようとした
⇒InputRow変数がNothingの状態で文字列を格納しようとしたため「オブジェクト変数また~」のエラーが発生した。

②Integer型などで宣言したInputRow変数に"InputRow,1"という文字列を格納しようとした
⇒数値型に対し文字列型を代入しようとしたため『型が違います』のエラーが発生した。

以降の処理から察するに、InputRow変数にはやはりセルを割り当てたいのではないかと思います。
使用する前に、
Set InputRow = ActiveSheet.Range("A1")
のように割り当てるセルを指定してあげれば、
InputRow = "InputRow,1"
はセルに"InputRow,1"という文字列を入れる処理として動作するようになります。

投稿2016/08/10 02:06

編集2016/08/10 02:09
jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iemon-yasu

2016/08/10 02:21

まずは、質問にお答えします。 『整合性確認』シートの内容は、 A列に便名/B列に残席数/C列にアップグレード座席の残席数/D列に出発時刻/E列に到着時刻です。 また、セット便となっているので、A-E(SEG1)の他にF-J(SEG2)にも同じ内容が数値や文字列を変えて入っています。 『整合性確認②』シートの内容は、 整合性確認のシートの、SEG1から1行路線を持ってきて、SEG"から、その乗継に最適な路線を2つ持ってくるという形になっております。 つまり、1行のSEG!に対して、2行のSEG2が来る形です。 上記を踏まえて、InputRowに入る内容及び、期待する動作としては、 InputRow=SEG1の行の内容 期待する動作は、1行ずつずらしてSEG2と対応させることです。 ご質問ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問