Excel vba をはじめて1ヵ月程度の初心者ですが、すいません質問させて下さい。
動的配列というのでしょうか?
その配列の中の最大値を求めたいのですが、よくわかりません。
アクティブシート内の図形で最前面以外の図形を消去しようと思ってます。
マクロで最大値の取得ができないので、暫定的にシートに計算させてしまっているのですが、マクロ上で最大値を求める方法がわかりません。
Sub testSZ()
Dim Num As Integer, Sum As Integer, Shp As Shape, Ary() As Variant, Mxm As Long
'++++++++++↓アクティブシート内の図形をカウント:=Sum
Sum = 0
For Each Shp In ActiveSheet.Shapes
Sum = Sum + 1
Next Shp
'++++++++++↓配列の数を決定
ReDim Ary(1, Sum)
'++++++++++↓配列に図形と図形のZオーダーを設定
Num = 0
For Each Shp In ActiveSheet.Shapes
Shp.Select
Set Ary(0, Num) = Shp
Ary(1, Num) = Selection.ShapeRange.ZOrderPosition
Num = Num + 1
Next Shp
'++++++++++↓配列内のZオーダー最大値を取得
Mxm = Application.WorksheetFunction.Max
'++++++++++↓最前面の図形以外を消去
Num = 0
Do
If Mxm > Ary(1, Num) Then
Ary(0, Num).Delete
End If
Num = Num + 1
Loop Until Sum = Num
Erase Shp
End Sub
Application.WorksheetFunction.Max[]
の[]にAryやAry(1,Num)をやってみたりしたのですが、
できないです。
どなたか御教授おねがい致します!!
No.4ベストアンサー
- 回答日時:
配列内の最大値などを求めるのは、通常は、全体をなめるしかないと思いますが、ご質問のケースですと、記録するときに同時に探してしまえば、新しくループをしなくてもすむでしょう。
(例えば下の一行を追加)Ary(1, Num) = Selection.ShapeRange.ZOrderPosition
If Ary(1, Num) > Mxm Then Mxm = Ary(1, Num) '←この行を挿入
Num = Num + 1
目的が最前面の図形以外を消去するだけならば、↑で同時に最大値の時の番号(Num)も記憶しておいて、消去するループではその番号以外を消去してあげればよろしいかと…
Shape(i)はZorder順に並んでいるみたいなので(For Eachでも同じ順みたい)、図形の消去だけが目的なら、別の考え方ですが、以下のように一回のループで配列を利用しなくても可能かと思います。(未検証)
flag = False '←最前面Shapeの検索フラグ
For i = ActiveSheet.Shapes.Count To 1 Step -1
If (Shpeの検索条件に合致するか) Then
If flag Then Shapes(i).Delete Else flag = True
End If
Next i
この回答への補足
(お礼の後の補足です)
Sub testTurn()
Dim Shp As Shape
For Each Shp In ActiveSheet.Shapes
Shp.Select
Application.Wait [NOW()+"0:00:01"]
Next Shp
End Sub
fujillinさんの御指摘があったので、検証してみたら、For Each 構文や Do Loop 構文もZorder順で選択しているみたいです。(Excel 2007)
fujillinさん、マクロが単純化できそうです!どうもありがとうございます!!
あとすいません。勘違いしてました。多次元の配列の最大値を求める場合もApplication.WorksheetFunction.Max(Ary)で出来ました。
今回の場合は図形が配列にSetされていたからダメだとわかりました。訂正します。。。
御回答ありがとうございます!!
やはり、多次元の配列の最大値を求める場合は総当たりしかないという事ですね!わかりました!!
やたら繰り返し構文が多いコードでしたので、fujillinさんの御指導で、マクロ高速化になりそうです!!
For Each 構文や Do Loop 構文が、Shape(i)がZorder順なのかどうかですが、codename順(sheets()のようにcodenameが取得できませんが、いわゆる新しい図形順)なのか、Zorder順なのかで未検証のままでした。他の要素も絡んでくると大変なので、手を付けてませんでした。確かにこれが明確ならば、かなりコードも単純化しそうですね!!
No.5
- 回答日時:
こんばんは。
VBAの教科書では、オブジェクトを確保するのは、配列にするよりも、コレクション・オブジェクトにするというように書いてあるかとは思います。
Dim colShp As New Collection
For Each shp In ActiveSheet.Shapes
colShp.Add shp
Next
このように確保します。
しかし、もともと、Shapes は、コレクションですから、Index を取っていけば、それで、ZOrderPosistion と一致しているはずですから、以下のようにすればよいと思います。オブジェクトですから、ひとつずつ削除するのではなく、一括して削除します。
Sub TestSample()
Dim i As Long
Dim mx As Long
With ActiveSheet
mx = .Shapes.Count
If mx = 1 Then Exit Sub '既に処理した場合は解除
.Shapes(1).Select '誤動作を避けるため
For i = 1 To mx - 1
.Shapes(i).Select False
Next i
End With
Selection.Delete
End Sub
なお、配列の最大値を取る方法には、裏技があって、ふつうは、1次元配列で、ワークシートのMax を取ります。検討してみてください。
御回答ありがとうございます!
なるほど、ZOrderPosition と Index がいっしょなのですね!!
New Collection というのがあるのですか。。。
やっと少しVBAをさわるのに慣れてきましたが、
まだまだ教科書的な基本事を知らないままですね。
Wendy02さんの描いて頂いたコードがスッキリまとめてくれていて、わかり安くて良いですね!!
どうもありがとうございます!!
No.3
- 回答日時:
回答2です。
戯けた回答をしてました。
objectが入ってますね。
で、素直に比較していったらどうでしょうか。
-------------------------------------
Dim myMax, i
myMax = ary(1, 0)
For i = 1 To sum
If ary(1, i) > myMax Then myMax = ary(1, i)
Next i
MsgBox myMax
-----------------------------------------
出来ました!!
配列をさらに変数に代入させるという事が、考えつきませんでした。
myRangeさんの御指摘の比較の総当たり方法で成功しました!!!
コードも描いて頂きありがとうございます!!
配列をさらに変数に代入させるというアドバイスも頂いたので、
ある意味、配列をわざわざ二次元にしなくとも二つの配列に増やしてもいいのではと思い、
配列を Ary1(0, Num) ←Shape を 格納 と Ary2(0, Num) ← ZOrderPosition を格納で
Mxm = Application.WorksheetFunction.Max(Ary2)
でもコードが動きました!!
出来て嬉しいです!ありがとうございます!!!
No.1
- 回答日時:
ActiveSheet.Shapes.Count
でどうでしょう?
この回答への補足
早速の御回答ありがとうございます!
すいません、ActiveSheet.Shapes.Count は突っ込まれるかと思いました。説明も不足してました。
あと、Erase Shp は Erase Ary です。すいません。。。
ActiveSheet.Shapes.Count を使わないのは、Shape 自体にいくつかの分類を作り名前を与えています。
(For each next の構文内に If Shp.name Like "~~" で指定)
複数の特定の同名を付けられた図形の中で、というのと、別のマクロで ZOrderPosition を逐一変えてしまっている、という点があり、話を複雑にしてしまっています。
今のところ配列内の最大値をマクロで求めたいと思っています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- PowerPoint(パワーポイント) ExcelのVBAコードについて教えてください。 3 2022/05/25 14:32
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) コード名シートA列と集計シートA列のコードが一致したら、コード名シートA5からk12の範囲をコピーし 1 2022/08/29 23:46
- Excel(エクセル) Excelのマクロについて教えてください。 4 2022/05/31 14:07
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- Visual Basic(VBA) マクロVBA 1シートをまとめる 閉じ方 初心者 SOS! 1 2022/06/17 14:54
- Visual Basic(VBA) まとめシートから集計シートへA列のコードが一致したら1行コピーするマクロをネット上で見つけました。こ 1 2022/08/30 14:11
このQ&Aを見た人はこんなQ&Aも見ています
-
「どうして捨てられないの?」前妻の物を捨てられない男性の心理って?
前妻の物を捨てられない理由に加え、捨てるための手段はあるのかを専門家に聞いてみた!
-
配列の中の最大値とそのインデックス番号を取得する方法
Visual Basic(VBA)
-
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
VBAで文字を反映させると255文字の制限になってしまいます。
Visual Basic(VBA)
-
-
4
初歩的な事だと思います。 Sub または Function が定義されていません。
Visual Basic(VBA)
-
5
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
[VB6/VBA] Variant型配列リテラ...
-
delete[]と、delete演算子の明...
-
六角形のマスの作り方
-
VBAによる第3、4水準文字の判定...
-
JSPの処理の途中で、JavaScript...
-
VB.NET2003 テキストボックスに...
-
JavaScriptで ブラウザの閉じる...
-
JavascriptでのExcel起動について
-
IEでalertのみを無効にする方法...
-
javascriptで「オブジェクトを...
-
csvファイルを読み込み、該当項...
-
正整数の半角数字かどうか判定する
-
禁止文字チェック
-
JavaScriptでテキス...
-
IE8開発者ツールでソースの修正
-
VBAの[cellsメソッドは失敗しま...
-
デザイン時のVisible=Falseは実...
-
「終了していない文字列型の定...
-
変換テーブルを使った、文字列...
-
Ajaxが動きません~『status=0』?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excel vba 配列内の最大値を求...
-
VB2008で数字の桁数を調べる...
-
VBA 多次元配列のクイックソー...
-
delete[]と、delete演算子の明...
-
六角形のマスの作り方
-
VBA セル範囲をVariant変数に代入
-
どんなオブジェクトでも表示で...
-
CollectionとArrayの呼び出し順
-
コードの意味 ("Scripting.Dict...
-
[VB6/VBA] Variant型配列リテラ...
-
JSPの処理の途中で、JavaScript...
-
VB.NET2003 テキストボックスに...
-
JavaScriptで ブラウザの閉じる...
-
「終了していない文字列型の定...
-
gas 全角数字を半角数字に変換
-
if(1){...}とはどういうことで...
-
正整数の半角数字かどうか判定する
-
htmlのfileタグに自動で値を入...
-
Vba SelStart、SelLen教えてく...
-
デザイン時のVisible=Falseは実...
おすすめ情報