アプリ版:「スタンプのみでお礼する」機能のリリースについて

表にフィルターをかけ、絞ったデータ(可視化セルのみ)を一次元配列として変数に入れるという動作を書きたいのですが、、。誰か教えて下さい。
表はヘッダーの下からは動的で10行の場合もあれば500行の場合があります。

質問者からの補足コメント

  • Excelのマクロでコーディングの勉強中でして。。
    詳しく知ってる方がいたら教えてください。。

      補足日時:2023/06/16 00:32
  • ご丁寧な回答をありがとうございます。

    >一次元配列ということは、対象は一列のみと考えて良いのでしょうか?
    対象は、表のヘッダーから下の可変データ1行分でございます。
    10行でもあれば500行というように、1行分のデータを1次元配列として変数に格納したいです。

    >表示セルには「必ず値がある」
    こちらは必ずしも値が全て入っているわけではありません。

    >一次元配列として取得したければ、プリミティブに、セル範囲をループで順にチェックして、表示されていれば配列に加えるという方法になると思います。
    こちらの内容が一番自分の中でフィットしたのですが、
    どのようにコーディングするのか教えてください。

    No.1の回答に寄せられた補足コメントです。 補足日時:2023/06/16 10:39
  • うーん・・・

    ありがとうございます。
    こちらのコードはこのまま記載して実行するとできますでしょうか。。

    No.2の回答に寄せられた補足コメントです。 補足日時:2023/06/16 20:22

A 回答 (3件)

横から失礼します


#1様の回答がすべてのような気がしますが
サンプルをいくつか作りましたので内容を確かめてみてください
配列にしたい対象列、範囲などが示されていませんので #2にあるように
ファンクションで書くべきでしょうかが、良く分からないようですので
A列の値のある最下段セルまでです
取得とDebug.Print 出力
セルに書き出す時に配列の利点を生かして出力などとしています
わざわざ一次元配列にするのはVariant配列で飛び行を一度に入れられない為でしょうか?

諄いようですが#1、2様の回答で完結されていると思いますので
BAは辞退します
サンプルについてもあくまで参考程度のものですので悪しからず
*コピーファイルなどで検証用にブックを作成して自己責任で確認してください

Sub test_01()
'配列(1列限定)一次元配列
Dim rng As Range, r As Range
Dim n As Long, i As Long
'可視セル範囲取得
Set rng = Range("A2", Cells(Rows.Count, "A").End(xlUp)).SpecialCells(xlCellTypeVisible)
'配列サイズ設定
ReDim arr(0 To rng.Count - 1)
'配列作成
For Each r In rng
arr(n) = r
n = n + 1
Next

'出力(取得)方法1
For i = LBound(arr) To UBound(arr)
Debug.Print arr(i)
Next
'出力先行がフィルタにかかる場合フィルタ解除
If (ActiveSheet.AutoFilterMode = True) Then ActiveSheet.Range("A1").AutoFilter
'出力(取得)方法2
Cells(2, Columns.Count).End(xlToLeft).Offset(, 1).Resize(UBound(arr) + 1) _
= Application.WorksheetFunction.Transpose(arr)
End Sub


Sub test_02()
'二次元配列
Dim rng As Range, Rng1 As Range
Dim n As Long, i As Long
'可視セル範囲取得
Set rng = Range("A2", Cells(Rows.Count, "A").End(xlUp)).SpecialCells(xlCellTypeVisible)
'作業列取得
Set Rng1 = Cells(2, Columns.Count).End(xlToLeft).Offset(, 1)
'コピーにより飛び行を加工(修正)
rng.Copy Rng1
'配列(Variant)
Dim arr As Variant
'作業列(データ)を配列に代入
arr = Rng1.Resize(rng.Count)
'作業列をクリアー
Range(Rng1, Cells(Rows.Count, Rng1.Column).End(xlUp)).ClearContents

'出力(取得)方法1
For i = 1 To UBound(arr)
Debug.Print arr(i, 1)
Next
'出力先行がフィルタにかかる場合フィルタ解除
If (ActiveSheet.AutoFilterMode = True) Then ActiveSheet.Range("A1").AutoFilter
'出力(取得)方法2
Rng1.Offset(, 1).Resize(UBound(arr)) = arr

End Sub


Sub test_03()
'A列可視セルを一次元配列に
'条件分岐により可視セルを取得する方法(対象を含むセルをループ)
Dim i As Long, n As Long
Dim arr()
For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
If Not Rows(i).Hidden Then
ReDim Preserve arr(n)
arr(n) = Cells(i, "A").Value
n = n + 1
End If
Next

'出力(取得)方法1
For i = LBound(arr) To UBound(arr)
Debug.Print arr(i)
Next

End Sub


Sub test_04()
'A列可視セルを一次元配列に(更に格納条件を付加する場合)
'予め可視セル範囲を取得する方法(可視セルでループ)
Dim rng As Range, r As Range
Dim arr()
Dim n As Long, i As Long
'可視セル範囲取得
Set rng = Range("A2", Cells(Rows.Count, "A").End(xlUp)).SpecialCells(xlCellTypeVisible)
For Each r In rng
'セルの値が3文字以上なら格納
'フィルタ条件を更に違う条件を設けて取得
If Len(r.Value) >= 3 Then
ReDim Preserve arr(n)
arr(n) = r.Value
n = n + 1
End If
Next

'出力(取得)方法1
For i = LBound(arr) To UBound(arr)
Debug.Print arr(i)
Next

End Sub
    • good
    • 0
この回答へのお礼

コードまで丁寧にありがとうございます。
コードをどう組むか教えて頂きたかったので、
言葉だけの説明だとまだ組めるレベルではなくて。。
欲しい回答をQちゃんさんに頂けたのでベストアンサーを受け取って欲しいです。
助かりました。ありがとうございます。。

お礼日時:2023/06/22 17:42

No1です。



>どのようにコーディングするのか教えてください。
No1に記載した通りなのですが・・・

以下は、一例ですが・・・
どういう使い方なのかが不明なので、関数化してあります。
配列にしたい Range を渡せば表示行のみの値を配列にして返します。
値の種類も不明なので、返される配列はバリアントの一次元配列です。
(添え字は1始まりにしてあります)

Function Column2Array(ByRef R As Range) As Variant
Dim c As Range
Dim i As Long, v()
i = 0

For Each c In R.Columns(1).Cells
If Not c.EntireRow.Hidden Then
i = i + 1
ReDim Preserve v(1 To i)
v(i) = c.Value
End If
Next c
Column2Array = v
End Function
この回答への補足あり
    • good
    • 2
この回答へのお礼

上記試しましたが、うまくいきませんでした。

お礼日時:2023/06/17 17:35

こんばんは



一次元配列ということは、対象は一列のみと考えて良いのでしょうか?
簡単な方法は、セル範囲のValue地をまとめてバリアント変数に入れると配列として取得できますが、これで得られる結果は二次元配列になってしまいます。(一列のみでも、二次元になります)
  変数 = セル範囲.Value
ただし、普通にセル範囲に対して上記を行うと非表示行も含まれてしまいますので、一旦、空き列(最終列とか)にコピペして、非表示行を無くしてから配列化するというひと手間が必要になります。


一次元配列として取得したければ、プリミティブに、セル範囲をループで順にチェックして、表示されていれば配列に加えるという方法になると思います。
あるいは、上記の方法で二次元配列に取得したものを、単純ループで一次元配列に転記するとかもないことはないでしょう。

VBAの場合、配列の添え字範囲を定義しておく必要があるので、
数が増加する毎に
 ReDim Preserve
で配列数を再定義してゆく方法もありますし、事前に全体数を把握してセットしておく方法も考えらえます。

表示セルには「必ず値がある」と仮定してもよいのなら、シート関数のSUBTOTALを利用することで、事前に全体数を把握することができるでしょう。
https://learn.microsoft.com/ja-jp/office/vba/api …
この回答への補足あり
    • good
    • 1

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A