トップページtech
1002コメント383KB

Excel VBA 質問スレ Part39 [転載禁止]©5ch.io

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2015/11/27(金) 20:36:45.35ID:9HV+ag/s
ExcelのVBAに関する質問スレです

                   ___
       ___      /____ヽ      ____
      /____\    | |´・ω・`| |    /___ヽ
      .l |´・ω・`|  ニX二 . ̄ ̄ ̄  二X二  |´・ω・`| l 俺たちに任せろ
      !、 ̄ ̄ ̄  ヽ   |       |    /    ̄ ̄ ̄/
       ヽ_/ヽ、  ヽ__)  \__/\_/.   /_/  ノヽ_/
             ̄                ̄ ̄

このスレはコード書き込みOKです。
作成依頼もOKですが、作成依頼限定ではありません。

コードが嫌な人・作成依頼が嫌な人は別スレ建ててください。

※前スレ
Excel VBA 質問スレ Part38 [転載禁止]2ch.net
http://peace.2ch.net/test/read.cgi/tech/1441619979/
0446デフォルトの名無しさん2016/01/16(土) 03:40:59.69ID:jFPwREdt
>>432
SendKeysはOSにそのキー入力を送ってねってお願いする命令
EXCELがOSからキー入力を受け取るには、マクロがひと段落する必要がある
マクロの途中でOSからの処理を受け取るにはDoEventsつかう
0447デフォルトの名無しさん2016/01/16(土) 04:26:02.48ID:fCKattgx
vbaでクラスとかいちいち作るヤツは死ねよ
0448デフォルトの名無しさん2016/01/16(土) 09:41:21.78ID:17wph6Lk
>>445
その辺がVBAでは悩みどころで、Entityクラスを一つ追加することは直でモジュールを一つ追加することになる。
細かいフォルダ階層が持てないVBAでは場合によってモジュールだらけになり、分かり辛くなる。

構造体は.Netで言う構造体のことを言ってるのかユーザー定義型のことを言ってるのか分からないけど、
前者は使えないし、後者はまずクラス化しないと他のモジュールで宣言して
それを引数で他のモジュールにあるメソッドや関数の引数に渡したりは出来ない。

直接指定しなければ使えないので、結局結合度は高いままになるし、
クラス化しても、同じ型を使って宣言した場合、同じモジュール内だと同じ参照先を指すため、非常に使い辛い。

結局のところコレクション、配列、ディクショナリやRecordSetを使って渡してやるとこらへんが妥当になる。

要は大きなシステムを開発する言語は兎も角、VBAにそこまで求めるなと言うことなんだろうな。
0449デフォルトの名無しさん2016/01/16(土) 10:38:53.02ID:EQwe8P3v
複数のプロシージャで使うパラメータなら、引数たらい回しより
シート・セルに範囲名を付けて使う方がマシかも知れない
0450デフォルトの名無しさん2016/01/16(土) 13:23:06.09ID:BVnENxs2
VBAのクラスは使ったことないし、ライブラリではクラスを定義する気ないなあ。
表に出ない使い方ならいいだろうけど、独自データ型をユーザーに使わせるのは旨くない。
ほかの言語ではそんな問題にはならないけど、VBAだとクラスのメリットが出にくいと思う。
0451デフォルトの名無しさん2016/01/16(土) 13:32:03.98ID:djcR4koj
>>450
お前の作ったライブラリを使わさせる時点でこの上ない苦痛なのだから
そんな事考えるだけ時間も無駄だ、好きにしろ
0452デフォルトの名無しさん2016/01/16(土) 13:43:22.10ID:/WAAZPFP
クラスはモジュールをパッケージ化するって目的の為だけに使う物だと考えると使いやすい。

VBAは環境が特殊なので普通のプログラムと同じような勉強の仕方すると混乱する。
クラスって名前がついているだけで、型安全の為に存在しているわけではないと気づけば応用範囲が広がると思う。
0453デフォルトの名無しさん2016/01/16(土) 14:25:05.94ID:BVnENxs2
>>451
食わず嫌いせずに使ってみてくれよ
0454デフォルトの名無しさん2016/01/16(土) 17:52:22.66ID:djcR4koj
>>453
そこまで言うなら使ってやるからどっかに上げといてくれ
0455デフォルトの名無しさん2016/01/16(土) 19:16:02.12ID:TOLCMvfB
プログラムのフレームワーク学習用にクラス使ったり
新入社員が仕事になるようクラスで必要なことを整理
するのも有効利用してると思うが
3Dレンダリングとかなるとクラスがないと
人と人とのコミュニケーションすらとれない感じだろ
必要とする度合いと取られる時間で決めたらいいのでは
0456デフォルトの名無しさん2016/01/18(月) 22:03:45.12ID:IuIvKytx
For Each はどうしてこう使いにくいのか?
0457デフォルトの名無しさん2016/01/18(月) 22:24:26.01ID:FooX/JpX
使いにくいかな?
0458デフォルトの名無しさん2016/01/18(月) 23:03:13.57ID:5Km6QlG1
VBのforeachは言語仕様上オブジェクトしか参照を渡してくれないからね
スマートにforeachで処理したつもりで全く反映されてなくてぐぎぎぎぎ
0459デフォルトの名無しさん2016/01/19(火) 00:05:50.65ID:XjyMc5te
>>421
vbaのclass使えば出来るんじゃないか?
0460デフォルトの名無しさん2016/01/19(火) 05:48:35.72ID:Knai0l7P
>>458
VBAにオブジェクト以外の参照型なんて無いからな
0461デフォルトの名無しさん2016/01/19(火) 08:57:29.57ID:hKwHZ0io
>>425
とにかく、場数を踏んで1個1個のメソッドについて使えるようにするしかないよ。
どうすれば車の運転が上手くなりますか? なんて質問と大差ない。
0462デフォルトの名無しさん2016/01/19(火) 11:40:00.29ID:1yi9x6jx
配列の値渡しの質問お願いします。

長いプロシージャを分割する作業をしているのですが、10個ある配列をモジュールレベル変数に置くか、その都度値渡しをするか、どちらがスピードは速くなるでしょうか?
パソコンが低スペですが、現在1分ぐらいかかるプログラムです。
0463デフォルトの名無しさん2016/01/19(火) 11:48:45.64ID:jGMD02BB
>>462
分割したプロシージャを数千万回とか呼ぶのでなければ、どっちにしても処理時間1分に
与える影響は1秒未満だと思う。

処理時間1分の中の10msとか100msの処理時間の違いなんて、気にしてもしょうがない。
0464デフォルトの名無しさん2016/01/19(火) 12:03:42.10ID:moFYOEmO
>>462
参照渡し(ByRef)でダメな理由は?
0465デフォルトの名無しさん2016/01/19(火) 12:57:02.14ID:1yi9x6jx
>>463
>>464
ありがとうございます。
値渡しする数が多すぎて、エラーを招きそうな気がしたもので、、、
0466デフォルトの名無しさん2016/01/19(火) 12:59:39.91ID:jGMD02BB
>>465
クラス使うと解決するかもね。
0467デフォルトの名無しさん2016/01/19(火) 13:32:37.47ID:hKwHZ0io
>>464
たとえば、var array = []; として、この配列のarrayをbayrefで渡せるの?
0468デフォルトの名無しさん2016/01/19(火) 13:58:55.16ID:Knai0l7P
>>467
お前は何の言語の話をしてるんだ?
0469デフォルトの名無しさん2016/01/19(火) 16:22:46.20ID:moFYOEmO
>>465
えーと、参照で渡すと意図しない書き換えが起こり得るって話かな?
でもそれはモジュールレベル変数にしても同じだし、何を問題にしてるのかよくわからない。
0470デフォルトの名無しさん2016/01/19(火) 17:49:50.46ID:1yi9x6jx
>>469
スピードとメモリの解放等が気になります。
実際はこの1分のプログラムを60〜120回ぐらいループさせたいのが目標で、0.1秒でも速くなると助かります。
また、一度モジュール変数多用でメモリ不足エラーが出てしまいました。
0471デフォルトの名無しさん2016/01/19(火) 18:12:17.93ID:jGMD02BB
>>470
何度も言うようだけど、速度改善を目標にするのは意味ないって。
1分かかる処理を60回繰り返すのだったら、0.1秒速くなっても、1時間の内6秒速くなるだけ。
もし本当に速度改善をしたいなら、処理ブロック毎に処理時間計測をすること。

本当に解決すべきは、そのメモリ不足エラーで、もし関数に配列の値渡しをしているなら、
それが原因かもしれない。

あるいは、60〜120回の繰り返し方が悪いのかもしれない。

public sub foo()
 for i = 1 to 60
  call メモリを大量に使う関数()
 next
end sub

なら、メモリを大量に使う関数のローカル変数は呼び出し終了後に自動解放されるので
問題はないが、以下のようにしているのなら問題がある。

public sub foo()
 for i = 1 to 60
  ' メモリを大量に確保して処理を行う
 next
end sub

これはfoo()が終了するまで、メモリを累積して確保し続ける。
確保した変数 = Nothingをnextの前に置けば、状況は改善するかもしれない。
あるいは、メモリ上のデータではなく、シート上のデータを相手にすれば、必要なメモリは
少なくて済む。(処理速度は遅くなるが)
0472デフォルトの名無しさん2016/01/19(火) 18:17:14.15ID:jGMD02BB
関数に変数を値渡しするというのは、元の変数のコピーを作って渡すということ。
つまり、参照渡しに比べて二倍のメモリが必要。

「メモリ不足エラー」というエラーではなくて「スタック領域不足」の場合は、また別の原因。
0473デフォルトの名無しさん2016/01/19(火) 18:42:41.96ID:1yi9x6jx
>>471>>472
わかりやすいご回答ありがとうございます。
メモリの解放タイミングが気になっていました。
まだまだ初心者で分かりにくい書き方ですいません。頑張ってみます。
0474デフォルトの名無しさん2016/01/19(火) 19:06:30.07ID:moFYOEmO
>>473
今現在データをどう渡しているのか書いてよ。
0475デフォルトの名無しさん2016/01/19(火) 19:36:21.61ID:1yi9x6jx
>>474
モジュール1
private tableA() as currency,tableB tableC
…動的配列10個程

sub 実行()
CALL A
配列の要素数決定しredim処理
CALL B
CALL C ←BCDで配列の中身を入れていく作業
CALL D
end sub

CALL先のプロシージャでは、ほとんど全ての配列を使っています。配列以外のこまごました変数だけ値渡ししています。

モジュール2
sub 全実行()
for n = 1 to 60
CALL 実行(name)
next n
end sub

こんな感じです。スマホからですいません。
0476デフォルトの名無しさん2016/01/19(火) 19:40:14.63ID:5AOetSsn
>>475
たぶんAccess VBA覚えた方が幸せになれる
0477デフォルトの名無しさん2016/01/19(火) 20:01:16.49ID:1yi9x6jx
>>475
スピードも変わるんでしょうか?
0478デフォルトの名無しさん2016/01/19(火) 20:36:15.66ID:Knai0l7P
>>475
結局配列何個確保してメモリ不足なんだよ

ちなみに
private tableA() as currency,tableB tableC
はたぶんBとCの間にカンマ抜けてるんだろうと思うけど
これでCurrencyになってるのはAだけで、BとCはVariantだぞ
0479デフォルトの名無しさん2016/01/19(火) 20:38:53.39ID:moFYOEmO
>>475
その10個の配列はずっと残っていてほしいということか?
ならいいんじゃね。
そうでなければ Sub 全実行のなかで作って各処理に参照渡しすればいい。
何も考え込むようなことじゃないら。
0480デフォルトの名無しさん2016/01/19(火) 20:39:52.19ID:moFYOEmO
ないらw
0481デフォルトの名無しさん2016/01/19(火) 20:54:20.44ID:5AOetSsn
無駄な事やってるだろうなってのは予想できるんだけど、
実際のデータをどう扱ってるのか分からないから解決出来ないもどかしさ。

ダミーデータと処理方法(VBAのではなく手作業的な)があれば効率のいいマクロ書けると思うんだけどな。
0482デフォルトの名無しさん2016/01/19(火) 20:58:28.16ID:Knai0l7P
>>476-477
何やってるか分からんけど、SQL一発で出来るような内容なら
ACCESS(とか他のDB)使えば速くなるかもしれん
ACCESSでも、VBAで自分でロジック組んでループまわすようなら、速くはならんと思うが
0483デフォルトの名無しさん2016/01/19(火) 21:06:55.44ID:UlyMCfxA
チューニングするならABCDのどこで時間が取られてるか調べないと対策のしようがない
excelから値取ってくるのに時間掛かってましたとかなら正直どうにもならん
0484デフォルトの名無しさん2016/01/19(火) 22:02:40.69ID:fUVEQkdb
シムレーションだろう
vbaだろうがcだろうが案外計算速度に違いはないが
variantとかだとそれはやめたほうがいいって感じ
0485デフォルトの名無しさん2016/01/19(火) 23:39:15.43ID:1yi9x6jx
質問主です。
みなさんありがとうございます。
上のコードは省略しすぎているので、型などは間違っていません。その他各部門のスピードは計測しなが改善しようと思います。
最後に質問なのですが、
上のモジュール2の
CALL 実行 が終わった場合、モジュール1の配列で使っていたメモリは解放されるということで間違いないでしょうか?
0486デフォルトの名無しさん2016/01/20(水) 00:11:38.99ID:XFqYG3t7
うん、間違いなくなくなくないかもしれないかもなくない

Private a As String
Sub test1()
a = "aho"
End Sub
Sub test2()
MsgBox a
End Sub

とかすればわかるかもしれない
0487デフォルトの名無しさん2016/01/20(水) 00:34:12.16ID:tnXkhLo5
ExcelでVBAマクロl動かしてる間
他のExcelの作業が中断してしまうのですが
どうにかなりませんか!
0488デフォルトの名無しさん2016/01/20(水) 00:41:59.97ID:uYf8rD9k
モジュールって基本的にはVBA実行中はずっと生きてる気がする
つまりモジュールレベルの変数は明示的にNothing代入するなりRedimするなりしないと開放されない気がする
0489デフォルトの名無しさん2016/01/20(水) 01:20:01.65ID:7T123+WA
>>487
もう一つ別に、Excelプロセスを起動したら?
0490デフォルトの名無しさん2016/01/20(水) 02:06:12.29ID:3JHsYJhz
話むしかえすけど
配列マジックを極める(ASCII)
って本をアマゾンでジャケ買いしたんだけど
VBAのことほとんど触れてねー
VBAでいうところの配列のテクニックを期待してたんだが残念。
やっぱ本はジャケ買いするもんじゃないな
0491デフォルトの名無しさん2016/01/20(水) 03:44:21.39ID:gC8iY3QI
>>487
ループ処理にDoEvents入れればループ処理宙は実行中に他の作業が出来る。
0492デフォルトの名無しさん2016/01/20(水) 07:11:18.99ID:xfIx1JoD
>>490
そんな本があるのか。
息するように配列を弄りまくっている俺でも、VBAの配列にはよくわからないところがある。
0493デフォルトの名無しさん2016/01/20(水) 08:21:54.61ID:biOEENiS
>>459
サブルーチンの中で定義したいと言う話
ファイル単位のスコープならモジュールでもできる
0494デフォルトの名無しさん2016/01/20(水) 10:03:37.62ID:TOXNslUJ
>>468
今気がついた。

普通にJavaScriptの構文で書いてた。最近VBAよりそっちの仕事のほうが多くて
ガチで気が付かなかった。
0495デフォルトの名無しさん2016/01/20(水) 10:37:40.75ID:HskUHurd
>>494
配列のarrayってVBAでいうジャグ配列(配列を要素とする配列)のことだろうか?
ByRefで関数に渡せるよ。
要素を参照で持てるか?という意味だとしたら、それはできない。
0496デフォルトの名無しさん2016/01/20(水) 11:25:41.73ID:TOXNslUJ
>>495
なるほどねぇ。

JavaScriptやってると配列関係の取扱いがVBAとはちょっと違うので、混乱するね。
0497デフォルトの名無しさん2016/01/20(水) 11:53:53.10ID:HskUHurd
例えば3つの配列
array1
array2
array3
をまとめて、
array_all = Array(array1, array2, array3)
なんてものを作ると、全部コピーになってしまう。
参照にしたくて色々試したが成功しない。
どうやら不可能なようだ。
0498デフォルトの名無しさん2016/01/20(水) 12:46:25.59ID:V5TARUOi
≫486>>487
度々ありがとうございます。
念のため、全てnothingで終わらせてみる実験をしてみます。長く走らせると不手際で解放されてないのかも知れません。
0499デフォルトの名無しさん2016/01/20(水) 18:19:33.52ID:xdXYdVv+
対象セルがどこかのセルで参照されているかどうか、
判定することはできるのでしょうか。

参照先のセルを得るのではなく、
「参照されているか、否か」を判定する方法です。

シート内の不要データの整理に使いたいと考えています。
0500デフォルトの名無しさん2016/01/20(水) 18:34:15.12ID:XFqYG3t7
isref
05014992016/01/20(水) 18:45:24.37ID:xdXYdVv+
>>500

あわせて調べてみました。
ttp://excel.onushi.com/function/isref.htm

isref()の引数で判定対象のセルを指定すればいいのですかね。
isref(cells(i,j)) みたく。
0502デフォルトの名無しさん2016/01/20(水) 19:48:55.16ID:XFqYG3t7
>>501
参照できたかどうかの関数らしい
ので間違いだった
セルの内容が参照の場合trueって説明だったから
isref使った時点で参照してるじゃんってミスでもないらしい
考えるにデータの入っていないセルに参照されてるかどうかの
プロパティつけるのは無駄かもしれないので
アイディアがないと無理そう
0503デフォルトの名無しさん2016/01/20(水) 20:55:20.57ID:uYf8rD9k
>>499
Range.Dependents プロパティ
05044992016/01/20(水) 22:25:06.28ID:xdXYdVv+
Dim range1 As Range

Dim returnValue As Range
returnValue = range1.Dependents

こんな感じでrange型変数に格納したあと、
if分で空(nothing)かを判定する、というのはどうなんでしょうか。
(自分で確認すれば良いのですが、ちょっと今は試せない状況で・・・)

ただ、どっちにしろ
>Dependents プロパティは作業中のシートでのみ有効で、
>リモート参照をトレースできないことに注意してください
ttps://msdn.microsoft.com/ja-jp/library/office/ff197707.aspx

なんて記述があるんで、
他シートをまたいでいるものに関しては
文字列判定をする必要がありそうですが。
0505デフォルトの名無しさん2016/01/21(木) 00:52:36.55ID:rehOk3U9
10行×5列の表があって、1列目に5個、2列目に8個、3列目に5個、4列目と5列目は空欄となっています。各項目は必ず1行目から入っています。
各列から1つずつ取って、それらを左から繋げた文字列(順列)を作りたいのですが、どのように書けば良いのでしょうか。
各列に何個要素があるかをカウントするところまでは書けたのですが、そこからよくわからなくなってしまいました
0506デフォルトの名無しさん2016/01/21(木) 01:06:23.00ID:X7n9A0oT
>>505
こんな感じか?

Sub macro1()
  r = 1
  For r1 = 1 To 5
    For r2 = 1 To 8
      For r3 = 1 To 5
        s = Cells(r1, 1) & Cells(r2, 2) & Cells(r3, 3)
        Cells(r, 6) = s
        r = r + 1
      Next
    Next
  Next
End Sub
0507デフォルトの名無しさん2016/01/21(木) 01:07:45.84ID:0jk7vnPh
>>499
Function RefCheck(CheckRange As Range) As Boolean
If CheckRange Is Nothing Then Exit Function
RefCheck = True
For Each x In ThisWorkbook.Worksheets
For Each y In x.UsedRange
For Each Z In CheckRange
If y.Formula Like "*" & Z.Address(1, 1) & "*" _
Or y.Formula Like "*" & Z.Address(0, 1) & "*" _
Or y.Formula Like "*" & Z.Address(1, 0) & "*" _
Or y.Formula Like "*" & Z.Address(0, 0) & "*" _
Then Exit Function
Next
Next
Next
RefCheck = False
End Function

あとは調べて無いけど同一シート内で参照していた場合もブック名とシート名を表示させる事が出来れば、
Addressの第四引数にTrue入れてチェックする事で間違いなく判定出来る。
0508デフォルトの名無しさん2016/01/21(木) 05:38:14.28ID:tGM9G3/P
>>506
ありがとうございます
そういう感じで必要十分なのですが、余談ですが同じような処理を繰り返すのでもう少しうまく処理できるのでしょうか?
0509デフォルトの名無しさん2016/01/21(木) 06:18:36.49ID:0jk7vnPh
>>508
Sub test()
Dim a(1 To 5), str(5), b() As String, index As Long
For i = 1 To 5
a(i) = Range(Cells(1, i), Cells(Rows.Count, i).End(xlUp)).Value
Next
For Each v1 In a(1): str(1) = v1
For Each v2 In a(2): str(2) = v2
For Each v3 In a(3): str(3) = v3
For Each v4 In a(4): str(4) = v4
For Each v5 In a(5): str(5) = v5
c = ""
For Each x In str
c = c & x
Next
ReDim Preserve b(index)
b(index) = c
index = index + 1
Next:Next:Next:Next:Next

For Each x In b
Debug.Print x
Next
End Sub

五桁固定。最低でも一桁当り2要素ないといけない。
桁数まで柔軟にすると、くっそ面倒だから自分でやれ。
0510デフォルトの名無しさん2016/01/21(木) 07:56:21.86ID:hkWWdNPn
>>509
だせぇ
0511デフォルトの名無しさん2016/01/21(木) 08:30:12.04ID:epD6nfy/
>>509
なぁ、出来もしないのなら、無理に回答しなくていいぞww

あとな、お前にお勧めのスレがある。
今までみた絶望的なソースコード [転載禁止](c)2ch.net
http://peace.2ch.net/test/read.cgi/tech/1429279230/
0512デフォルトの名無しさん2016/01/21(木) 08:48:35.32ID:Jdl8/hrx
初心者のコードってすげぇと思うよな。
とても真似できん。
自分にない発想があるなって劣等感があるよ。
0513デフォルトの名無しさん2016/01/21(木) 09:46:20.45ID:pkb4zgJk
>>505のやつ4行くらいでできないかな。
入出力2行、 桁数可変で本体処理2行。
右からやるか左からやるか...
0514デフォルトの名無しさん2016/01/21(木) 10:15:19.09ID:f+IaIVwa
昨日か一昨日かのWindows UpdateでList View使ってるファイルがおかしくなった。。。
0515デフォルトの名無しさん2016/01/21(木) 12:00:32.16ID:tGM9G3/P
>>509
ありがとうございます。
条件を書くと、以下のようです。

1)各列に何個の要素があるかは動的(
2)何列あるかも動的(>>506のネストの数は3だが、ここが何回ネストするかが動的になる)
3)組み合わせの仕方は左から順にのみで、並び替えの必要はない(樹形図的)
4)要素の文字数も動的で、何桁か決まってはいないし、数字もあれば文字列もある

私は条件2のうまい書き方がよくわからず、結局、何列あるかを調べて、if文で1列なら〜2列なら〜3列なら>>506というようにしています。
0516デフォルトの名無しさん2016/01/21(木) 12:06:31.84ID:X7n9A0oT
>>515
そういう場合は再帰を使え
0517デフォルトの名無しさん2016/01/21(木) 12:13:08.74ID:pkb4zgJk
>>516
かなり無理があるのでは?
組み合わせの数だから相当の量になる。
0518デフォルトの名無しさん2016/01/21(木) 12:15:50.60ID:epD6nfy/
>>505
つーか、そんなのユーザ定義関数でいいだろ。
0519デフォルトの名無しさん2016/01/21(木) 12:54:35.53ID:jus49kmC
>>517
組合せの数だけネストするわけじゃないだろ
0520デフォルトの名無しさん2016/01/21(木) 13:30:20.23ID:X7n9A0oT
>>515
再帰ってのはこんなふうに書くんだよ
ループのネストの段数が不定でも問題なく動く
VBAの仕様でデータが300列ぐらいあるとメモリ不足を起こすけど、300列の順列なんて出そうとしたら人類が滅亡するほど時間がかかるんで実用上は問題ない

Sub main()
  Call Recursive(1, "")
End Sub

Sub Recursive(c As Long, s As String)
  max_row = Cells(Rows.Count, c).End(xlUp).Row
  If Cells(max_row, c).Value <> "" Then
    For r = 1 To max_row
      Call Recursive(c + 1, s & Cells(r, c))
    Next
  Else
    Debug.Print s  ' データ出力
  End If
End Sub
0521デフォルトの名無しさん2016/01/21(木) 13:36:58.95ID:P+RPuePi
テーブルの重複行削除の際に、削除する行を指定させる方法を教えてください。
以下は、単純にマクロ記録したものです。
Sub Macro1()
Range("F5").Select
ActiveSheet.Range("テーブル2[#すべて]").RemoveDuplicates Columns:=Array(1, 6, 7), _
Header:=xlYes
End Sub
11列分テーブルの、1、6、7列目が重複したものを削除するのですが、
これに、8列目のの数値が小さいほうを削除、大きい方を残したいです。
わかりますでしょうか?よろしくお願いします。
0522デフォルトの名無しさん2016/01/21(木) 15:34:42.41ID:epD6nfy/
>>520
減価償却費の計算とかではよくつかってる。
0523デフォルトの名無しさん2016/01/21(木) 20:02:04.58ID:RqTcmjez
>>521
聞きたい事は分かったが残念な事に答えが分からんのだよw
0524デフォルトの名無しさん2016/01/21(木) 20:35:34.37ID:0jk7vnPh
>>521
Sub test()
Dim c(2), m As Collection, del As Range
Do
Set del = Nothing
Set m = New Collection
xdata = Range(Cells(1, 1), Cells(Rows.Count, 11).End(xlUp)).Value
i = i + 1
If i > UBound(xdata, 1) Then Exit Do
c(0) = xdata(i, 1): c(1) = xdata(i, 6): c(2) = xdata(i, 7)
For j = 1 To UBound(xdata, 1)
If xdata(j, 1) = c(0) And xdata(j, 6) = c(1) And xdata(j, 7) Then m.Add j
Next
If m.Count Then
p = 0
For Each x In m
e = True
If p Then If xdata(p, 8) > xdata(x, 8) Then e = False
If e Then p = x
Next
For Each x In m
If x <> p Then If del Is Nothing Then Set del = Rows(x) Else Set del = Range(del, Cells(x, 1).EntireRow)
Next
If Not del Is Nothing Then del.Delete
End If
Loop
End Sub

これで動かないかな
0525デフォルトの名無しさん2016/01/21(木) 20:40:55.77ID:xJzWoKjV
1空き列に連番を振る
28列目で降順に並び替える
3removeduplicate
41の列で並び替える
51の列を削除
05264992016/01/21(木) 23:00:34.27ID:0tyN2uzx
dependentsを使って、それっぽいことはできました。
下記は、セル(1,1)とそれを参照するセルを返して選択させる
ということをさせようとしています。

Sub Macro1()

Dim c As Range

Set c = Cells(1,1)
Set c = Union(c,Cells(1,1).Dpendents)

If Not c Is Nothing Then c.select

End sub

これだと、.Dependentsの対象(1,1))がどこかで参照されていれば問題ないのですが、
参照していないとエラーになってしまいます。

何か方法はないでしょうか。
0527デフォルトの名無しさん2016/01/22(金) 00:36:15.19ID:gKLeKKXn
>>526

Sub Macro1()
  Dim c As Range

  Set c = Cells(1, 1)
  On Error Resume Next
  Set c = Union(c, Cells(1, 1).Dependents)
  On Error GoTo 0
  
  If Not c Is Nothing Then c.Select

End Sub
0528デフォルトの名無しさん2016/01/22(金) 04:12:46.72ID:7u0WrXxg
>>520
遅くなりました。ありがとうございます。忙しくてまだ試せていませんが、勉強します!
0529デフォルトの名無しさん2016/01/22(金) 07:09:40.91ID:hQb40WO/
>>520
何度もだせぇの書くなよ
質問者に悪いと思わんのかw
0530デフォルトの名無しさん2016/01/22(金) 08:58:29.38ID:1YiOGDCq
>>520
でもそれ、別に別の関数に投げるんでも全く問題ないわけだが。わざわざそういう
書き方した所で、大したメリットがない。
0531デフォルトの名無しさん2016/01/22(金) 09:52:25.70ID:p0qaIBjS
VBAでの再帰はかなり制約的に書かないといけないから使いにくい。
右からの畳み込みで表現するといいと思う。
0532デフォルトの名無しさん2016/01/22(金) 11:27:13.63ID:aQA1bWN9
>>524
遅くなってすいません。
思い通りに実行出来ました!ありがとうございました!
0533デフォルトの名無しさん2016/01/22(金) 12:38:57.86ID:6pvUxBV3
最近、If文の1行書きを知ったのですが、例えば、10個の分岐を10個のelseifを使って分岐させるのを1行書きに書き換えるとスピードはやはり落ちるものなんでしょうか?
elseifを使うと、該当したら他のelseifコードはスルーしますが、1行書きifを使うと、一応ぜんぶ判定しにいくので。しかし可読性は1行書きの方なんですよね〜
0534デフォルトの名無しさん2016/01/22(金) 13:04:43.89ID:1YiOGDCq
>>533
select文も使うのが普通ですよ。
0535デフォルトの名無しさん2016/01/22(金) 13:27:56.38ID:KXk9pxmd
>>533
100万回実行して、10ms未満の違いしかないようなことを気にしてもしかたがな。
0536デフォルトの名無しさん2016/01/22(金) 14:29:53.04ID:p0qaIBjS
>>533
複数の if が排他的でなかったら論理的に違うことをやってるのはわかるよね?
スピードなんかより
0537デフォルトの名無しさん2016/01/22(金) 19:44:34.49ID:turD6O79
'mycollectionという変数に、キーワードを100〜1000個入れて、
'セルの値と該当しない場合、その行を削除するみたいなことをやりたいのですが、
'こんなことは可能でしょうか?
Sub test01()
Dim lRow As Long, i As Long
'mycollection = "田中","山田","佐藤","鈴木","井上"・・・・・・・手動でキーワードを入れる
lRow = Cells(Rows.Count, 1).End(xlUp).row
For i = lRow To 2 Step -1
If Cells(i, 2).Value <> mycollection Then
Range(i & ":" & i).Delete
End If
Next i
End Sub
0538デフォルトの名無しさん2016/01/22(金) 20:00:51.94ID:ax/jel29
その例のような感じにするならキーワードを配列に入れておいてFilter()したらいいのでは
ただそのキーワードというもののあり方によってはフィルタ系の機能を使ったり正規表現を使った方がいいかもしれないぞ
0539デフォルトの名無しさん2016/01/22(金) 20:15:48.39ID:turD6O79
>>538
Filter使ったことないですが挑戦してみます。
キーワードは、文字列で完全一致のもので絞り込めたらいいのですが、filterで問題ないでしょうか?
0540デフォルトの名無しさん2016/01/22(金) 20:16:29.80ID:50X4sy+n
1000個ある名前をセルに入れるなり変数にセットするのを
vbaでやればあとはどうやってもできるんじゃないか
手動でキーワードを入れるってのをできるだけ
自動化するって問題だけだろ
0541デフォルトの名無しさん2016/01/22(金) 20:40:19.73ID:KhXVHsnG
>>529-531
より良いコード書いてからほざけ、ボケ
0542デフォルトの名無しさん2016/01/22(金) 20:43:53.69ID:turD6O79
>>540
mycollection(1000)として、filterをどのように使えばよいのでしょうか?
初心者ですいませんが、よろしければご教授お願いたします。

f = Filter(mycollection,.Cells(i,2).Value)
f(0)がエラーとなるならばといったようなコードでしょうか?
0543デフォルトの名無しさん2016/01/22(金) 21:11:50.86ID:pRZKDnHi
>>537
Sub Test(Keyword As Range, CheckList As Range, CheckColumn As Long)
Dim del As Range
For i = CheckList.Row To CheckList.Rows.Count
For Each x In Keyword
If Cells(i, CheckColumn) Like x Then
If del Is Nothing Then
Set del = Cells(i, 1).EntireRow
Else
Set del = Range(del, Cells(i, 1).EntireRow)
End If
End If
Next
Next
del.Delete
End Sub

Keyword = キーワードを入れたセルを指定する。
CheckList = チェックしたいリストの範囲を入れる。
CheckColumn = キーワードを判定したい行を入れる。
0544デフォルトの名無しさん2016/01/22(金) 21:15:29.86ID:p0qaIBjS
くそ、ケンカを売られたぞ
0545デフォルトの名無しさん2016/01/22(金) 21:18:48.91ID:d8M8QDrI
VBAの変数名ってどこまで大丈夫なの?
「らんま1/2」みたいな演算子っぽいのが混ざった名前も変数にしたいんだけど何か方法ある?
■ このスレッドは過去ログ倉庫に格納されています