前回も同じような質問をしたのですが、
同一グループ内において、点数の高い順から3つを転記したいのです。
質問して恐縮ですが、関数ではありません。
VBAで実行したいのです。
私の認識では、同一グループは、連想配列しかないと思っていましたが、別の方法があるのでしょうか?
実現したい方法か下記のURLです。
https://gyazo.com/382fa71fe40ccd9de063d12f88f6cf46
連想配列でかんがえていたのですが、煮詰まってしまいました。
お手数ですが、ご教示をお願いします。
よろしくお願いします。
No.5ベストアンサー
- 回答日時:
以下のマクロを標準モジュールに登録してください。
----------------------------------------------
Option Explicit
Sub ベスト3()
Dim maxrow As Long '最大行番号
Dim wrow As Long '行番号
Dim st_row As Long '開始行番号
Dim en_row As Long '終了行番号
Dim ws As Worksheet '作業シート
Dim prev_cls As String '前回のクラス
Dim crnt_cls As String '今回のクラス
Dim Points() As Variant '点数のテーブル
Dim ctr As Long 'データ件数
Set ws = ActiveSheet 'アクティブシートを処理する
maxrow = ws.Cells(Rows.Count, "A").End(xlUp).Row 'A列 最終行を求める
prev_cls = ""
st_row = 2
For wrow = 2 To maxrow '2~最終行まで繰り返す
crnt_cls = ws.Cells(wrow, 1).Value 'クラス取得
If crnt_cls <> prev_cls Then '前回のクラスと異なるなら
If prev_cls <> "" Then '前回のクラスが空白以外なら点数の出力を行う
Call flush_data(ws, st_row, en_row, Points)
End If
prev_cls = crnt_cls '今回のクラスを前回へシフト
st_row = wrow '現在行を開始行へ設定
ctr = 0 'データ件数をクリア
End If
ReDim Preserve Points(ctr) 'データ件数分の配列の要素を確保
Points(ctr) = ws.Cells(wrow, "B").Value '点数を保存
ctr = ctr + 1 'データ件数加算
en_row = wrow '現在行を終了行へ設定
Next
Call flush_data(ws, st_row, en_row, Points) '点数の出力
MsgBox ("完了")
End Sub
'点数の出力
Private Sub flush_data(ByVal ws As Worksheet, ByVal st_row As Long, ByVal en_row As Long, ByVal Points As Variant)
Dim p1 As Variant '1番目に高い点数
Dim p2 As Variant '2番目に高い点数
Dim p3 As Variant '3番目に高い点数
Dim wrow As Long '行番号
p1 = GetMax(Points) '最大値取得
p2 = GetMax(Points) '最大値取得
p3 = GetMax(Points) '最大値取得
For wrow = st_row To en_row '開始行~終了行まで繰り返す
ws.Cells(wrow, "C").Value = p1
ws.Cells(wrow, "D").Value = p2
ws.Cells(wrow, "E").Value = p3
Next
End Sub
'Pointsから最大を検索し、その値を返す。最大値は次回の検索のためにEmptyに設定しておく。
Private Function GetMax(ByRef Points As Variant) As Variant
Dim i As Long
Dim max As Variant
max = Empty
'最大値を検索する
For i = 0 To UBound(Points)
If IsEmpty(Points(i)) = False Then
If IsEmpty(max) = True Or Points(i) > max Then
max = Points(i)
End If
End If
Next
'最大値をEmptyに置き換える
For i = 0 To UBound(Points)
If Points(i) = max Then
Points(i) = Empty
End If
Next
GetMax = max
End Function
No.6
- 回答日時:
こんばんは、
既に回答もアドバイスも出ているように思いますが、
>私の認識では、同一グループは、連想配列しかないと思っていましたが、
>別の方法があるのでしょうか?
と言う事で、別案を考えてみました。
少し疑問に思った点ですが、A列が昇順になっていますが、なぜB列は降順にしないのでしょうか?
B列を大きい順にしてしまえば、同じグループの上3行を抜き出せば良い事になると思います。
条件を設定するにも連想配列の方が分かりやすいと思いますが、敢えてべたにループさせてみました。
遊びのような、コードなのでスルーして頂いて良いと思いますが、一応、掲示させていただきます。
添付図を参考にしています。
Option Explicit
Sub sample()
Dim i As Long, j As Long, n As Integer
Dim tmp, ary(2)
Call Range(Cells(2, "A"), Cells(Cells(Rows.Count, "A").End(xlUp).Row, "B")).Sort _
(Key1:=Range("A2"), Order1:=xlAscending, Key2:=Range("B2"), Order2:=xlDescending)
tmp = Cells(2, "A").Value
i = 1
Do
i = i + 1
If tmp = Cells(i, "A").Value Then
If j < 3 Then
ary(j) = Cells(i, "B").Value
j = j + 1
End If
n = n + 1
Else
Cells(i, "C").Offset(-n).Resize(n, 3) = ary
Erase ary
tmp = Cells(i, "A").Value
i = i - 1
n = 0
j = 0
End If
Loop While Cells(i, "A").Value <> ""
End Sub
回答ありがとうございました。
コード参考にさせていただきます。
申し訳ないですが、ベストアンサーは、tatsumaru77さんにさせていただきます。
本当にありがとうございました。
No.4
- 回答日時:
こんばんは
>連想配列しかないと思っていましたが、別の方法があるのでしょうか?
VBAからでもほとんどのシート関数が利用できますので、ほぼ計算せずとも結果を得ることができます。
https://docs.microsoft.com/ja-jp/office/vba/api/ …
関数を利用する別の方法として、結果を表示したいセルに(あるいは、一時的に空きセルを利用して)関数式を設定して、値を読み込むというものも考えられます。
まぁ、これらの方法だと、VBAで計算するというよりも関数式を考えるところで、ほとんどの計算をしていることになりますけれど。
No.2
- 回答日時:
どのような結果をお望みなのかはわかりませんが、クラス毎で点数の上位3つ(大中小はなんだろう?)と言うのなら、降順で並び替えても出来ますしね。
連想配列(Dictionaryオブジェクトなど)でも出来るでしょう。
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/v …
このようなものもあります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) エクセル・スプレッドシートで、一定数を超えたらゼロから再累計する方法 8 2022/05/28 03:52
- Excel(エクセル) 重複したデータ(空白は除く)のVBA表記について 4 2022/08/15 07:28
- Visual Basic(VBA) 重複したデータ(空白は除く)のVBA表記について 5 2022/08/15 12:41
- Visual Basic(VBA) マクロについて教えてください。 4 2023/06/06 09:06
- Visual Basic(VBA) 【困っています2】VBA 追加処理の記述を教えてください。 2 2022/08/26 11:42
- Visual Basic(VBA) 複数指定セルの可視セルのみを別シートに転記するVBAについて 2 2022/05/27 21:19
- Excel(エクセル) 【困っています】VBA 追加処理の記述を教えてください。 1 2022/08/25 22:54
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Visual Basic(VBA) vba 等間隔の列に対しての計算 6 2022/05/17 20:15
- Visual Basic(VBA) VBAで、特定の文字より後を削除して残った数値を文字列に変換と特定の文字より前も削除したい 3 2022/04/15 19:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA一覧取得 再投稿
-
VBA指定行削除
-
エクセルVBAについて
-
VBA ユーザーフォーム ボタンク...
-
VBA 複数のエクセルから一つの...
-
【ExcelVBA】値を変更しながら...
-
VBAに詳しい方教えてください。
-
VBA listBoxについて
-
Vba 実数および実数タイプの変...
-
現在のブックを閉じないで、マ...
-
Excelのマクロについて教えてく...
-
エクセルのマクロについて教え...
-
VBA マウスクリックとキーボー...
-
VBA レジストリの値の読み方に...
-
2つのマクロでチェックボックス...
-
エクセルのマクロについて教え...
-
エクセルのマクロについて教え...
-
ExcelのVBAコードについて教え...
-
【マクロ】1つのマクロの中に...
-
エクセルについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
LV_ITEM構造体のメンバlParamに...
-
DataGridで特定の行のスタイル...
-
Varianntメモリリークについて
-
4バイト整数を使っているため
-
python3 各引数の意味と、引数...
-
DirectX C++/CLIで作成したDLL...
-
VC++.NET2003でユーザー関数内...
-
ExcelのVBAについて
-
MFCで水平スクロールバー
-
DirectInputが上手く動きません;
-
VB2008にてWEBアプリケーション...
-
エクセルVBAで、条件に一致する...
-
変数名の付け方
-
「タイプ初期化子が例外をスロ...
-
河合塾のクラス分けについて
-
同じクラスにならない確率を教...
-
インスタンス参照でアクセスで...
-
複数の変数を宣言する時、同時...
-
3年間同じクラスになる確率
-
private static という変数の修飾
おすすめ情報