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

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

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

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

Q&A

解決済

2回答

1103閲覧

指定した文字列のある行番号が知りたい

ma2hiro

総合スコア159

VBA

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

0グッド

0クリップ

投稿2021/11/16 02:46

編集2021/11/16 02:50

お世話になっております。

VBA - 文字列をVBAで見つける方法を知りたい。|teratail
にて数式は"()"で括らないと計算してくれないと理解しました。

今現在セルの値が”37期”との場合のセルの行数が知りたいと思い
以下のように実装しました。

vba

1Dim year As Integer, gKi As String 2 3Private Function getGyou() As Integer() 4 5 Dim tmp As Integer 6 tmp = year - 1984'yearはこの関数呼ぶ前に値代入している 7 gKi = Str(tmp) & "期" 8 gKi = Replace(gKi, " ", "")'セルの中に半角スペースがあったら削除 9 '配列を宣言 10 Dim kiGyouArray(), i As Integer 11 12 Set searchRng = Range("B:B") 13 ' 最初はFindで検索 14 Set rng = searchRng.Find(gKi) 15 ' 検索結果を一時保存 16 Set tempRng = rng 17 i = 1 18 ' 条件にあったセルが見つからなければNothingが返るので何もしません 19 Do While Not rng Is Nothing 20 Debug.Print rng.Row 21 kiGyouArray(i) = rng.Row 22 i = i + 1 23 ' FindNextで検索を継続 24 Set rng = searchRng.FindNext(rng) 25 ' すべて検索し終えると最初に戻るので、Addressで確認! 26 ' これを忘れると無限ループになるので注意! 27 If rng.Address = tempRng.Address Then 28 Exit Do 29 End If 30 Loop 31 getGyou = kiGyouArray() 32End Function 33

ですが呼ぶ↓内で

Sub 利益の色更新_Click() Dim wb As Workbook, fname, zantei As String Dim month, tatejiku, tatejikuji As Integer fname = Range("B1").Value year = Range("B8").Value month = Range("B9").Value month = Format(month, "##") tatejiku = 10 + month tatejikuji = month - 2 zantei = Range("B10").Value Dim tounendoGyuu() As Integer Set wb = Workbooks.Open(fname) With Worksheets("利益") tounendoGyuu = getGyou :

の tounendoGyuu = getGyou で

コンパイルエラー: 配列には割り当てられません。

取得した行番号の該当月に値を入れる予定です。

何故かとググった
【VBA配列定義】Array:配列には割り当てられません。というエラーはなぜ出るか|あんもちブログ
には
Dim kiGyouArray As Variant
とすれば良いと書いてあったのでそうするとコンパイルは通るのですが
kiGyouArray(i) = rng.Row にて

実行時エラー:13 型が一致しません

となってお手上げ状態なのです……

大変申し訳ないのですが
何か情報をお持ちな方はコメント頂けますようお願い申し上げます。

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

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

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

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

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

guest

回答2

0

取り敢えずDim kiGyouArray()だけの状態ですと要素数が無の配列となってしまい、何も入れることができません。
要素数がわからないために動的配列にしているのだと思いますが、この形の動的配列は以下のようにRedim Preserve kiGyouArray(i)を使ってその都度要素数を定義しなおす必要があります。

ただ、これで型の不一致エラーが出るのも変なので、まだ別の問題が潜んでいる気はします。

VBA

1Do While Not rng Is Nothing 2 3 Redim Preserve kiGyouArray(i) 4 Debug.Print rng.Row 5 kiGyouArray(i) = rng.Row 6 i = i + 1 7(以下略

投稿2021/11/16 04:08

Usirow

総合スコア364

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

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

ma2hiro

2021/11/16 04:41 編集

ありがとうございます。 [VBAのReDim Preserveとは:エクセルマクロ・Excel VBAの使い方/配列] (https://www.relief.jp/docs/excel-vba-what-is-redim-preserve.html) で要素を増やせる事が分かりました。 ``` ▼Preserveとは 配列に格納されている値を残したまま、配列の最後の次元の要素数を変更するために、ReDim文の中で使用するキーワード ``` 本当にありがとうございました。
guest

0

ベストアンサー

回答の前に、下記の点は修正しておきましょう。

  • 宣言せずに使用している変数がある(searchRng, rng, tempRngなど)

Dim searchRng As Range, rng As Range, tempRng As Rangeと宣言しておく。
バグの原因になりますので、モジュール先頭でOption Explicitを宣言して変数宣言を矯正するようしておくといいでしょう。あと、オプションで自動でOption Explicitを装入してくれるように設定しておくいいでしょう。
下記参照。
Office TANAKA - 今さら聞けないVBA[Option Explicitって何?]

  • 型を指定せずに宣言している変数がある

vba

1 Dim wb As Workbook, fname, zantei As String 2 Dim month, tatejiku, tatejikuji As Integer

上記の fname, month, tatejiku は型指定していないのでVariant型になります。ちゃんと一つずつ型指定しましょう。

vba

1 Dim wb As Workbook, fname As String, zantei As String 2 Dim month As Integer, tatejiku As Integer, tatejikuji As Integer
  • 数値をInteger型で宣言している

Integerだと最大32,767なので、シートの行数以下なのでオバーフローエラーになる可能性があります。Long型で宣言しておいたほうがいいでしょう。


で、本題の質問のエラーの原因ですが、

Private Function getGyou() As Integer()
で返り値を整数型の配列で宣言していますが、
Dim kiGyouArray(), i As Integer
ここでは、型指定していないのでVariant型の配列になっています。
getGyou = kiGyouArray
ここで、整数型の配列にVariant型の配列を代入しているので、提示のエラーになります。


上記の点をもろもろ考慮して、下記のコードで動作確認できました。

vba

1Option Explicit 2Dim year As Integer, gKi As String 3 4Private Function getGyou() As Long() 5 year = 2021 6 Dim tmp As Integer 7 tmp = year - 1984 'yearはこの関数呼ぶ前に値代入している 8 gKi = tmp & "期" 9' gKi = Replace(gKi, " ", "") これは不要、Str(tmp) も不要、Str(tmp) とすると余計な空白が付く 10 '配列を宣言 11 Dim kiGyouArray() As Long, i As Integer 12 Dim searchRng As Range, rng As Range, tempRng As Range '追加 13 Set searchRng = Range("B:B") 14 ' 最初はFindで検索 15 Set rng = searchRng.Find(gKi) 16 ' 検索結果を一時保存 17 Set tempRng = rng 18 i = 1 19 ' 条件にあったセルが見つからなければNothingが返るので何もしません 20 Do While Not rng Is Nothing 21 Debug.Print rng.Row 22 ReDim Preserve kiGyouArray(i) 23 kiGyouArray(i) = rng.Row 24 i = i + 1 25 ' FindNextで検索を継続 26 Set rng = searchRng.FindNext(rng) 27 ' すべて検索し終えると最初に戻るので、Addressで確認! 28 ' これを忘れると無限ループになるので注意! 29 If rng.Address = tempRng.Address Then 30 Exit Do 31 End If 32 Loop 33 getGyou = kiGyouArray 34End Function

関数呼び出し

vba

1 Dim tounendoGyuu() As Long 2 tounendoGyuu = getGyou

追記

  • 動的配列でサイズを指定せずに使用している

これは書き忘れましたが、他の方が回答されているので参照してください。

投稿2021/11/16 04:07

編集2021/11/16 04:17
hatena19

総合スコア33795

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

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

ma2hiro

2021/11/16 05:01 編集

本当に度々ありがとうございます。 Option Explicit でバグがいっぱい出てきたので今後は付けないと駄目ですね…… お教え頂いたURLには ``` BEの[ツール]-[オプション]で開く[オプション]ダイアログボックスの[編集]タブに[変数の宣言を強制する]というチェックボックスがあります。これをオンにしておくと、それ以降に挿入されたモジュールでは、先頭にOption Explicitが自動入力されます。 ``` とありましたがので今後はそのチェックを付けるようにします。 それで 配列AsInteger と配列AsLongが混ざっていて上手く出来なかった模様でした。 ご助力により解決出来ました。 本当にありがとうございました。感謝いたします。
ma2hiro

2021/11/16 06:30

と思いましたが デバッガで追っている時は良いのですが(そのシートがアクティブになっているので) ``` Set wb = Workbooks.Open(fname) With Worksheets("利益") Worksheets("利益").Select ' 「利益」のシートを選択 ``` とSelectしないと上手く動作しないことを気をつけるため追記失礼いたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問