プロが教えるわが家の防犯対策術!

VBAを勉強し始めた初心者です。

https://oshiete.goo.ne.jp/qa/5219546.html の回答を参考に空白を上のセルを参照して入力するように書きました。

Sub Fill_In_Blank ()
Dim i As Integer
Dim S As String
S = ""
For i = 18 To Range("D" & Rows.Count).End(xlUp).Row
If Cells(i, 3) = "" Then
Cells(i, 3).Value = S
Else
S = Cells(i, 3).Value
End If
Next i


End Sub

しかし、添付画像のようにうまくいきません。C28以降のセルで入力されてしまいます。テーブルを使用しているのがいけないのでしょうか。調べてコードの意味を理解していますが(理解しているつもりだけなのかもしれません)、どこが間違っているか解りません。ご教示願います。

「エクセル VBA 空白のセルに上のデータ」の質問画像

A 回答 (7件)

こんばんは!



横からお邪魔します。
No.2さんのお礼欄に
>表示されていない「ゼロ」が隠れていたこと

すなわちオプションの「ゼロ値のセルにゼロを表示する」のチェックが外れているのでしょうか?
また、空白に見えてもスペースが入っているセルが存在する可能性もあるかもしれないので、
その辺を対処してみました。

尚、C18セルは何らかのデータが入っているという前提です。

Sub Sample1()
 Dim i As Long, myStr As String
  For i = 18 To Cells(Rows.Count, "D").End(xlUp).Row
   If Cells(i, "C") <> 0 And Len(Trim(Cells(i, "C"))) > 0 Then
    myStr = Cells(i, "C")
   Else
    Cells(i, "C") = myStr
   End If
  Next i
End Sub

※ 質問文のコードではD列で最終行を取得するようですので、
D列に表示されていない何らかのデータがある場合はその行まで表示されてしまいます。
これはどの列で最終行を取得するか?によって変わってくると思います。m(_ _)m
    • good
    • 0
この回答へのお礼

助かりました

ありがとうございます。皆様に感謝です。ご提示頂いたコードの結果は、私の求めるものにかなり近いです。まだ、D列の一番最後が、ずらずらとテーブルの一番下まで続いてしまっています。テーブルに張り付けているのですが、テーブルの行を増やしたり、減らしたりすと、イミディエイトウィンドウに『?Range("D" & Rows.Count).End(xlUp).Row』を入力した数が変化することがわかりました。皆様にご協力いただき、本当に感謝しております。テーブルに張り付けなければ、うまく作動するのでその方向でいきます。

お礼日時:2019/06/11 18:45

Oが隠れているだけなら、条件判断を“″(ブランク)でなく0にすればいい。

ブランクも0で扱ってくれます。

 Cells(なんとか)=0


 Sの型宣言はこの場合削除するかバリアント型にすればいいと思います。
    • good
    • 0
この回答へのお礼

なるほど!ありがとうございます。試してみます。

お礼日時:2019/06/11 18:45

ブランクに見えるけど、セルにスペースとか入ってませんか?


このマクロで動きましたよ。

仮に別なシートに適当なデータ入れて試してみたら?
    • good
    • 0
この回答へのお礼

返信ありがとうございます。別のシートで、簡単な数字と文字を入力し、同じ配置で試した時は思い通りに動きました。しかし、こちらのシートではうまく作動しません。。

お礼日時:2019/06/10 17:35

あっ!なるほど


No2さんの意見が正しそうですね
画像を見落としていました(T-T)
    • good
    • 0

追記


最終行からxlUpで参照していますが、18行目からのxlDownの方が良いのでは?
『Range("D18").End(xlDown).Row』
ついでに文字列の退避を除外したバージョンを記載しておきます
Sub Fill_In_Blank()
 Dim i As Integer
 With ActiveSheet
  For i = 18 To .Range("D18").End(xlDown).Row
   If .Cells(i, 3) = "" Then
    .Cells(i, 3).Value = .Cells(i - 1, 3).Value
   End If
  Next i
 End With
End Sub
    • good
    • 0
この回答へのお礼

ありがとうございます。コピペして試してみました。。残念ながら、動かないです。。。。すみません。。。

お礼日時:2019/06/10 17:37

こんにちは



以下でテストしてみました。

新しいシートのC18セルから下方に、
 1)ランダムに飛び飛びで値を入力し
 2)さらに、(範囲の終わりを示すため)D列の適当なセルに値を入力
した状態で、ご提示のVBAを実行してみると、C18以下の空白セルにその上と同じ値が入力されます。
(C18から空白セルが続く場合は、その部分は空白のまま。)

これは、多分、質問者様が予定した処理通りの内容ではないかと思います。

>C28以降のセルで入力されてしまいます。
そのシートに、何らかの仕掛けが施してあるってことはありませんか?
(シートチェンジのイベント処理が設定してあるとか…)
    • good
    • 0
この回答へのお礼

ありがとうございます。
いろいろとさわってみて、分かったことが2つあります。
1つ目は、データを他のシートからコピーして貼り付け(値のみ)しているのですが、表示されていない「ゼロ」が隠れていたこと。過去に、オプションの設定のところで変更していたんだと思います。
2つ目は、貼り付け先がテーブルのため、No.1さんのご指示に従い、イミディエイトウィンドウに『?Range("D" & Rows.Count).End(xlUp).Row』を入力すると、一番最後の行より2つ多い数字が返ってきました。テーブルを削除して、「ゼロ」を手動で削除したとき、うまくいきました。

お礼日時:2019/06/10 18:17

コードは基本的に合っていますが、Range参照およびCells参照が曖昧です。

Generalに記載していますがこれはワークシートですか?ThisWorkbookですか?標準モジュールですか?
どちらにせよ一度イミディエイトウィンドウに『?Range("D" & Rows.Count).End(xlUp).Row』と入力してEnterしてみてください。その答えが27でない場合は別のシートが参照されている可能性があります。
特定のシートのみで使用するのであれば『Sheet名』を、複数のシートで使用するのであれば『ThisWorksheet』や『ActiveSheet』などシートを特定してからRangeやCellsを使ってください。
前提としてサブルーチンを呼び出す時には対象のシートが選択されていることが条件です。(例外あり)
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
ワークシートです。
イミディエイトウィンドウに『?Range("D" & Rows.Count).End(xlUp).Row』と入力してみました。「27」ではなく「29」が出てきました!!

シートを下記の通り指定してみました。

Sub Blank_Fill_In()
Dim i As Integer
Dim S As String
S = ""
For i = 18 To Worksheets("シート名").Range("D" & Rows.Count).End(xlUp).Row
If Cells(i, 3) = "" Then
Cells(i, 3).Value = S
Else
S = Cells(i, 3).Value
End If
Next I

End Sub

まだ動きません。結果は同じ状態です。本当にすみません。まだVBAを勉強し始めて1週間なので、シートの指定方法が間違っていたらご教示ください。

お礼日時:2019/06/10 17:46

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!