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

エクセル2003です。VBAは初心者です。

ある列(Aとして)にデータがあって、A列をキーに昇順に並べ替えます。(1行目が見出し。)

その後、2行目の値を基準値として、
ループで3行目から4行目、5行目…と順に値を見ていき基準値と比較して、
値が異なったら基準値でフィルタをかけて印刷し、
現在の値を新たな基準値として次のループを行う、
という処理を行っていました。

上記の時は数字4文字(0001、0100等)という前提だった為、空白や4文字の数字以外は
事前にチェックしてエラーメッセージを出していたのですが、
新たに「01」や「00001」も「0001」と同じ値として扱うことにしました。

この場合オートフィルタで「01」や「00001」と「0001」を同時に抽出する事は可能でしょうか?

また無理な場合、どのような処理にすればよろしいでしょうか?


今の所、2つの値の文字数を取得(Len関数)し、
RIGHT関数で1文字取得。

1文字を比較して異なれば別とみなし印刷、
同じなら次はRIGHTで2文字取得して2文字を比較…
これを少ない方の文字数分行う。

その後、文字数が多い方の文字列からLEFT関数で差分の文字数分取得し、
オールゼロなら同じとみなし、オールゼロでなければ別とみなす…。

という様な処理を作っている途中なのですが、

まずCOBOLのように、不特定な文字数の文字列に対して「ALLZERO」かどうかを見る
方法はあるでしょうか?

また、処理が長引いているような気もするのですが、
これ以外に有効な方法はあるでしょうか?

教えていただけると助かります。
よろしくお願い致します。

A 回答 (3件)

文章で表現することも必要だが、実例を挙げて説明すべきだ。


何のことか判りにくい。無駄な記述も多いので焦点がぼやけているのでは。
>2行目の値を基準値として、ループで3行目から4行目、5行目…と順に値を見ていき基準値と比較して、値が異なったら基準値でフィルタをかけて印刷し、現在の値を新たな基準値として次のループを行う、という処理を行っていました。
など本質問に、書く必要があるのか。過去にやっていたというだけで本質問に直接関係がない場合は、質問の中に書かないこと。
ーーー
>VBAで「1」、「01」等を同じ数字とみなすには
これをしたいなら、「セルの値」として、別の(同行別列)セルに統一したデータをつくるべきなだけ。
Format関数などで文字列に統一するか、VALで数値に統一すれば仕舞いではないか。なぜ質問が出るのか
ーー
上記で「別のセルに」といった理由は、
それとエクセルを使うものとして、根本的なことがわかっていない。VBAの初心者だとしても、エクセルも良くわかってない。
エクセルは、「セルの値」の「学」(まなび)である場合が多いのだ。「セルの値」に対比するものは「表示形式適用後の見た目」だ。
ソートやフィルタは、セルに「実現している値」を元に処理するようになっているのだ。
VBAで言えば、Rangeオブジェクトに対するメソッドになっているのがそれを意味する。
セルなどを前提にしないVBプログラムでは、プログラムの中で修正キーをつくり、その値に基づいてソートなどの処理をするのは自由だ。
それでもソートについては、一旦配列などに修正キーを「全」レコード分作らねばならない場合が多い。
またレコード処理で出来る課題で、1レコード内で修正した値を変数に作成し、其れで処理できる場合はあろう。(前後関係・全体関係を問題にしないで良い場合)
しかしソートなどは、プログラムの中の変数に、修正データを作るだけでなく、セルの「値」として実現せ(作ら)ねばならない(表示形式の見た目の結果ではダメということも意味する)。ソートなどの場合はそれも各行セルに対応して、全行のデータがセル範囲(普通同一列データ)に作成されて居ないとダメ。
フィルタの場合もFilterメソッドを使うなら、前もってセルの「値」として実現せ(作ら)ねばならないのだ。
ルール(例「1」、「01」等を同じ数字とみなすには)適用後のデータがシートに必要ということ。
1レコードづつ  該当かどうか判別していくなら、変数にプログラムで修正データを作って、そちらで考えればしまい。
ーー
すなわちエクセルでは
プログラムで、1レコード分の変数に修正値を作る+エクセルのRangeオブジェクトのメソッドなどに頼って、修正後変数値を使って処理はできない。
これらは「単独」レコード(行)を処理するのでなく、セル範囲で考えざるを得ないもの(ソート)や、セル範囲のデータ全部に
一遍に、同じルールを適用する(フィルタ)ものが多い。
これがあるお蔭でVBAコード1行でソートが済んでしまうのでありがたいわけ。フィルタも同じ。
例外に見えるソートのオプション特にユーザー指定(例日・月・火・・順)の並べ替えなどがあると、いうかもしれないが、それらはマイクロソフトが別途、問題を引き取って、作業列などを作り、処理しているわけで、我々ユーザーには、舞台裏側は見せてないだけ。
===
総括すると
基本的にはエクセルでは空き列に、修正データを作って、そのシートデータにの新設列のデータに対して処理することを基本と心得ること。
本質問では修正データを作るコードは簡単なものだ。それをメインテーマに質問をしてないだけ。
それでは無駄をかんじて、もっと無駄を省けないか、などは、相当エクセルも習熟し、VBAに熟達してからゆっくり考えること。
多分無いと思うが。
    • good
    • 0
この回答へのお礼

確かにまだエクセルを理解できていないですね。
勉強します。

ありがとうございます。

お礼日時:2011/04/17 22:27

やりたいことが、よくわからないのですが、


>新たに「01」や「00001」も「0001」と同じ値として扱うことにしました。
これは、先頭の0は無視するという意味ですか?
コンピュータの問題を解くとき、このように例をあげて考えてはいけません。
どういうルールなのか、一般規則を見つけることが、問題解決の第1歩です。

前に書いたとおり、先頭の0を無視するのでよいなら、
・数字しか出てこないのなら、Val関数で、数値化してから比較する。
・数字以外の文字もありえるなら、Mid関数で左から順に1文字ずつ調べ、0以外の文字が出たところで、それより右の文字だけ取り出して(Mid関数は取り出す文字数を十分大きくしておくと、それより右の文字を取り出すことができる) 比較する。
のどちらかとすればよいでしょう。
    • good
    • 0
この回答へのお礼

すいません説明不足でした。

現在は数字以外の文字も含み、表示形式も標準以外を考慮しなければならない
状態で作成しています。

一般規則を見つけることですね…
ありがとうございます。

お礼日時:2011/04/17 22:25

>不特定な文字数の文字列に対して「ALLZERO」かどうか



そういう手順を組んでしまうなり,関数を作成してしまえばどうとでもなります。
例:
dim buf as string
buf = "0000"
if application.substitute(buf, "0", "") = "" then
msgbox "buf is all zero"
end if


>他の手

val関数で数値化してしまう手もあります。
例:
dim buf as string
buf = "0010"
msgbox val(buf)

ワークシート上で数式によって数字の文字列を数値化してしまい,そちらでフィルタをかける手もあります。
例:
A列にそういった文字列が記入されている
D列でそれらを数値化する
range("D2:D" & range("A65536").end(xlup).row).formula = "=A2+0"
range("D:D").autofilter field:=1, criteria1:="=1"

オートフィルタの代わりにadvancedfilterを使ってみる手もあります。マクロ以前に「フィルタオプションの設定」のエクセルの機能について習熟しておく必要があります。
    • good
    • 0
この回答へのお礼

勉強不足でした。

助かりました、ありがとうございます。

お礼日時:2011/04/17 22:22

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