ウインドウにデータを入力するプログラムは不可能なのでしょうか?
私は今までコマンドラインから使う市販の科学系ソフトに大量のケースのパラメータを入力するため、
Perlで一度に入力し、結果もまとめて一つのファイルにするプログラムを作成して使っていました。
しかし、この度、ソフトがWindows用にバージョンアップしたため入力もウインドウに書き込み、
結果も一つずつ新しいウインドウに出力されます。
このようなソフトの場合は以前のようなプログラムは作成できないのでしょうか?
Perlでは難しいと思いますのでどなたか可能な言語を知っておられたら回答お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

キーボードの操作を記録・再生できるソフトのうち、記録ファイルがテキスト形式で直接編集できるようなものを利用すると良いと思います。



キーボードマクロ&マウスマクロ KMmacro
http://www.vector.co.jp/soft/win95/util/se211440 …


> 結果もまとめて

結果がどういう出方をするか?ですね。
テキストフィールドに出るのなら、そこからコピペとか。
画面に表示されるんなら、画像として保存していくとか。再利用がしにくいですが。


過去に使った事のある製品版のものですと、VisualTestが使いやすかったです。
作成したアプリケーションを自動で試験するためのツールですので、値の取得や比較、自動処理なんかまで。

--
他の方法としては、入力値をExcelにまとめておいて、VBAのSendKeyコマンドなどを使って自動で動作させる方法とか。
サンプルが見当たらないので書籍の紹介ですが、

C&R研究所のホームページ - アッと驚く達人のExcel VBA実践技&上級大全
http://www.c-r.com/mo_tevb03.htm

| ●Excelからメモ帳を起動してデータを書き出す・・・・・・237
| ■「SendKeys」でアプリケーションを操作するには事前にアプリケーションをアクティブにせよ!

なんかに書かれているハズ。

参考URL:http://www.vector.co.jp/soft/win95/util/se211440 … http://www.c-r.com/mo_tevb03.htm
    • good
    • 0
この回答へのお礼

お礼が遅れてすいませんですた。大変役に立ちました。
色んな人に聞いたのですがキーボードやマウスの動きを記憶できるソフトは知りませんでした。
ループや条件までプログラムできて大変役立ちました。
時間があれば自分でVBAからでも作ってみようと思います。ありがとうございました。

お礼日時:2005/04/28 11:22

#3さんお書きの方針がよいと思います。

PerlでもActivePerlだと、Win32::GUITest::SendkeysやSendMouse でGUI操作ができるようです。
あと下記のようなソフトもあります。

お金がかけられるなら、#3さん紹介のような、「GUIアプリの開発時に使うテストツール」を買うと楽だと思います。

参考URL:http://www.vector.co.jp/soft/winnt/util/se332987 …
    • good
    • 0

以前はコマンドラインからのみ動作するアプリだったのが、Windowsコンソールがついたものに変わったということで、そちらでの入力作業もマクロ化したいということなんでしょうかね。



で回答としては
そちらのアプリの仕様次第となってしまします。
Windowアプリでもコマンドライン対応をするものは多々あり、特に基がコマンドアプリだったものがバージョンUPしただけのものであるなら以前のコマンドはそのまま受け付けるタイプのものが多いです(アーカイバ系アプリは殆どがそうです)。
それでしたらおそらく以前の方法でそのまま使えるかと思います。
全く別アプリということであれば、その仕様書なりヘルプを確認して下さい。コマンドラインからの起動や引数などについての言及があればその仕様に従えば同様の処理ができると思います。
また設定ファイルなどで起動オプションをつけたりすることが出来るものもありますので、その手の場合でしたらiniファイルを直接編集してそれからアプリを起動させたりでマクロ化することも可能でしょう。

で全くそういうのがないアプリの場合でしたら、ご希望のことはほぼ不可能です。
ある程度の仕様等が公開されているアプリでしたらそれなりのことが出来ますが、おそらくされていないでしょうから、例えばキーイベントを発生させて所定の項目を選択させてそこに文字列を流し込むというようなことぐらいは可能ですが、キーイベントによる操作はPCの処理状況などによっては期待通りの動作はしませんから難しくあります。
この手のことならプログラム言語は簡単なVBとかでも出来ます。そのアプリ自体を乗っ取るのならC系の方がお勧めです。
    • good
    • 0

ウィンドウというのが何を指しているのかわからないですが、GUIならVBかVCでいいのではないでしょうか

    • good
    • 0

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QDreaWeaverを使ったCSSルール設定でブロック項目についての質問です。

DreamWeaverでCSSルールを設定しているのですが質問です。

「ブロック」のカテゴリの「縦に整列」というところのCSSルールに

『上』と『上付き』があるのですが
どちらを選択しても文字がテーブル上部にくっつきます。
この2つの違いは何でしょうか?

DreamWeaverをお使いの型でお詳しい方がいらっしゃいましたら
回答宜しくお願い致します。

Aベストアンサー

vertical-align:
の指定です。
詳しくは参考URLを。
図解入りで解説があります。

参考URL:http://www.seo-equation.com/html/css/vertical-align

Qプログラムのパラメータの自動入力

お世話になっております.

以下のようなプログラムがあります.

1. hoge.exe を実行すると
2. Dosウインドウが立ち上がり
InputA : _ #入力待ち状態になる,Enterを押すと3.へ
3. inputAにパラメータを入力すると
InputB : _ #再び入力待ち状態になる
4.すべてのパラメータを入力すると,プログラムが走って結果がテキストファイルに出力される.

そこで質問ですが,この入力(InputA,InputB...)を自動化する方法はあるでしょうか?
ソースは無く,exeファイルしか現在は手元にありません.
いくつかパラメータを変更して,出力ファイルを比較したいのですが,良い方法は無いでしょうか?
助言を宜しくお願い致します.

Aベストアンサー

そういうキー入力には
(1)キー入力専用のプログラムを使用しているもの
(2)汎用の入力の仕組みを利用していて、その標準状態が「キーボードからの入力」になっているもの
の大きく2つのケースがあります。

(1)の場合は、キー入力を再現する必要があります。
例えば:
・UWSC のような自動化ツール
・TeraTerm等の端末ソフトでのマクロ(WindowsのTelnetを有効にして、端末ソフトでWindowsにログイン→マクロ実行、と手間にはなる)

(2)の場合、リダイレクトを使って変更できる可能性があります。

入門書でのCのプログラムで、
「scanf : キーボードから入力」
とか書いてあることがありますが、正確には
「scanf: 標準入力から入力」
であり、
「標準入力: 端末操作時は、デフォルトではキーボードになっていることが多い」
なので「scanf: キーボードから入力」として動作する、ということになります。

そのプログラムが、このような入門書レベルの入力方法で作成されていたら、
hoge.exe < foo.txt
とすることで、標準入力がキーボードから foo.txtに切り替わり、 scanfは foo.txtから読み込みます。

そういうキー入力には
(1)キー入力専用のプログラムを使用しているもの
(2)汎用の入力の仕組みを利用していて、その標準状態が「キーボードからの入力」になっているもの
の大きく2つのケースがあります。

(1)の場合は、キー入力を再現する必要があります。
例えば:
・UWSC のような自動化ツール
・TeraTerm等の端末ソフトでのマクロ(WindowsのTelnetを有効にして、端末ソフトでWindowsにログイン→マクロ実行、と手間にはなる)

(2)の場合、リダイレクトを使って変更できる可能性があります。

入門書でのCのプロ...続きを読む

Qメッセージルールについて

迷惑メールで困っているんです、No.1684807のstallowber さんの質問の続きになりますが、IPアドレスの数字をoutlook EXのメッセージルールの“送信者にユーザーが含まれている場合”の項目に転記して受信拒否または削除に指定できますか、それとoutlookのメッセージのルールは何件までぐらい設定できますか

Aベストアンサー

 「IPアドレスの数字を・・・・・・できますか」は無理だと思うし、意味が無いと思いますが、迷惑メール対策で困っておられて、しかも送信者がアドレスをいろいろ変えてくるので・・・・もしくはそういった送信者が多数あり、さらに困っていらっしゃる・・・・・という質問と解釈して回答申し上げます。勘違いだったら読み飛ばしてくださいね。

 一つの迷惑メールを選択して「メッセージ」メニューから「メッセージからルールを作成」を選んだら、そのメールの送信者アドレスが自動的に条件として設定されるのでここでルールを作っていきます。

 もっと簡単な方法があって、そのメールを選択したら「メッセージ」メニューから(ここまでは上と同じですね)、「送信者を禁止する」を選ぶと、
 「***@****が禁止されたユーザーの一覧に・・・・・・・のメッセージを削除しますか?」
 とメッセージが現れるので、「はい」と押すと以降、その送信者からのメールは自動的に削除されます。迷惑メール対策ならこっちのほうが簡単です。
 そしてこの送信者はルール一覧ではなく、「ツール」メニューから「メッセージルール」のなかの「禁止された送信者の一覧」タブに登録されます(設定解除するには同タブでアドレスを解除する)。

 もう一つの質問、「設定できるルールの件数」ですが、
 簡単に申し上げると、OutlookExpressであれば一つのルールの中で12の条件と12の動作を一つまたは複数指定できます。が、むやみにルールを追加しないほうがいいです。
 「outlookのメッセージのルールは・・・」とあるので、ひょっとしたらMicrosoftOutlookについてお尋ねかもしれないのでついでに申し上げますが、MicrosoftOutlookならば27の条件、27の動作を設定できます。そして、迷惑メール対策機能も便利です。

 

 「IPアドレスの数字を・・・・・・できますか」は無理だと思うし、意味が無いと思いますが、迷惑メール対策で困っておられて、しかも送信者がアドレスをいろいろ変えてくるので・・・・もしくはそういった送信者が多数あり、さらに困っていらっしゃる・・・・・という質問と解釈して回答申し上げます。勘違いだったら読み飛ばしてくださいね。

 一つの迷惑メールを選択して「メッセージ」メニューから「メッセージからルールを作成」を選んだら、そのメールの送信者アドレスが自動的に条件として設定される...続きを読む

QVBScriptで作成したプログラムで別のプログラムを動かしたいです。

表題の通りですが、作成したスクリプトで実行すると下記のようなエラーが出てしまいます。ほかのWindowsアプリケーション(電卓やメモ帳など)ではちゃんと動きます。
何が原因か教えて頂けませんでしょうか?
お願い致します。

 指定したファイルが見つかりませんでした。
 コード:80070002
 ソース:(null)

Aベストアンサー

>電卓等は動くので
メモ帳や電卓はPathが通っているところにプログラムがあるのでフルパスで記述しなくても動きます。

>WindowsXPの・・・だからでしょうか?
上にも書きましたが、プログラム名(○○.exeなど)のみを指定して動くものはPathが通っているところにあるからです。
なので対処方法としては、
・プログラムをフルパスで指定する
・プログラムをPathが通ったところに配置する
・Pathにプログラムの場所を追加する
のどれかで動くと思います。

QOutlook Expressでメッセージルールを作るのですが、効果が

Outlook Expressでメッセージルールを作るのですが、効果がありません。メッセージルールに、送信者、件名、宛先、本文中等の各項目へ、禁止する言葉や人名等色々書き、それらを含むメールは「削除」するように設定するのですが、相変わらず受信欄へ入ってきます。同じやり方で以前は出来て、殆ど削除欄へ入っていました。今では全て受信欄へ入ります。ご指導の程宜しくお願い致します。

Aベストアンサー

>既に全てを削除して設定しなおしたのですが、ダメで
した。

そうなると設定内容を確かめないと判断できないですね。
あとはOEの不具合も考慮して再インストールを考えるかですが、再インストールはIEの入れ直しが必要になり面倒です。他のソフトへ乗り換える方が楽だと思います。

Q平文を解読するとまた別の平文の文章になる、といった暗号文の作成ソフトというものは可能でしょうか?

たとえば

「あなたを愛している」

という文章があったとして、それをある暗号解読ソフトにいれると

「おまえなんか嫌い」

という文章になる、といったような、全く違う意味の文章になるような暗号ソフトというのはありうるのでしょうか?

ありうるとすれれば、どのような原理で作成できるものでしょうか?
当方プログラムは素人なのですが、お教えいただけましたらありがたく存じます。

よろしくお願いいたします。

Aベストアンサー

私の知っている範囲では「埋めこみ」という方法を使います。
たとえば.連歌の先頭か末尾の1文字の語を横に読めば目的の意味になるが.漢字で書かれた言葉では待った区別の意味になるという方法です。
欧米では.延々いろいろな言葉が続いていますが.奇数をテン.偶数をツー(逆かも)としてモールス符合になっていたとか.の話しを聞きます。

QWindowsメールのメッセージルール

Windowsメールのメッセージルール
メッセージメニューからメッセージからルールを作成をクリックすると1番で「差出人にユーザーが含まれている場合」という項目があります。
この意味はメールをくださった方が自分のパソコンのユーザー名を相手が受信した時に差出人の欄に表示されるように設定しているということでしょうか?

教えてください。
宜しくお願い致します。

Aベストアンサー

メッセージルールは、質問者さんが受信するメールに適用するものです。

この場合の、[ユーザー]はだれでもよいのです。
自分から自分に送信する場合のユーザーは、ルールを設定する際には、自分になります。


差出人、すなわち、受信メールの「送信者」は誰でもよく、ルールの中で「ユーザー」と仮に呼称しているだけです。

「宛先にユーザーが含まれる場合」も同じです。

アドレスでもよいですし、受信したメールの送信者覧にある表示名など「文字列」であれば、何でもよいです。
次の過去ログNo.3でお答えしてますが、参考にしてください。
http://okwave.jp/qa/q5945404.html

QPerlで早いプログラムを作りたい

perlの初心者です。
一つの配列の構成要素が100~1000のものが1000個ほどあります。
ある配列の一つの要素が他の配列に何個づつあるかを調べています。
作ったプログラムは次の三つですがとても遅く、もっと早い方法があれば
教えてください。
1.foreach $a(@hairetsu1){
    $n=0;
    foreach $b(@hairetsu2){
      $n++ if $a =~ $b;
    }
  }
2. foreach $a(@hairetsu1){
    $n=grep(/$a/,@hairetsu2);
 }
3. for($i=0;$i<length(@hairetsu1);$i++){
   $n=0;
   for($j=0;$j<length(@hairetsu2);$j++)
     $n++ if $hairetsu1($i) =~ $hairetsu2($j);
   }
 }
上が一番早く下に行くほど遅いですがあまり違いはありません。
よろしくお願いします。

perlの初心者です。
一つの配列の構成要素が100~1000のものが1000個ほどあります。
ある配列の一つの要素が他の配列に何個づつあるかを調べています。
作ったプログラムは次の三つですがとても遅く、もっと早い方法があれば
教えてください。
1.foreach $a(@hairetsu1){
    $n=0;
    foreach $b(@hairetsu2){
      $n++ if $a =~ $b;
    }
  }
2. foreach $a(@hairetsu1){
    $n=grep(/$a/,@hairetsu2);
 }
3. for($i=0;$i<length(@hairetsu1);$i++){
...続きを読む

Aベストアンサー

#1 の nipotan です。

> 「=~」「==」「eq」いずれも同じと思っていました。

これらの違いを正確に理解しないと、根本的に手を加えるたびに脳内に未曾有の混乱を招くだけです。
=~ は左辺スカラーを対象にパターンマッチングや置換に使う (正規表現)
== は左右の値が数値的に等しいかを比較する比較演算子 * (01 == 1) は True *
eq は左右の値が文字列的に等しいかを比較する比較演算子 * ("01" eq "1") は False *
基本なので「はじめての~」系の本をお読みになって理解を深めたほうがいいと思います。

> やっていることは@hairetsu1(asd,dfg,zxc・・・・これが100~1000続く)の配列
> が1000配列程度あって、たとえば@hairetsu1の要素dfgが@hairetsu2にあるかあれ
> ばいくつあるかということを調べたいのです。中身は数字ではありません。

あ、そういう事だったんですね。根本的に勘違いしていました。
ただ「あれば」というのを先に調べる為に、結局は配列要素全体から対象の存在をさらって調べることになるので、「あるというのがわかってるんだから端っからカウントを始めたほうが早い」と考えられます。

> ># 重複チェック用テンポラリハッシュを生成
>
> というのが使えそうですがよく理解できません。
> なぜハッシュを使うのかよくわかりませんが
>
> next if exists $tmp{$a};
>
> の$tmp{$a}は$aがあったら数えないで次にいくということですか
>
> $tmp{$a} = 1;
>
> これはなにをしているのですか。本からの理解ではkey $a の値は1
> となってしまいますが・・・・

これは、「チェックしたか否か」を見るためのフラグ (Flag) です。あるかないかのブール値 (Boolean) なので、値はなんでもいいです。一応ワタシの作ったのはフラグなので実際にカウントした数値 ($n) は入りません。別に入れてもいいんですが、質問文にある 1. 2. 3. は、それぞれ $n の値を全て上位のループのたびに Flush ($n = 0 したり $n に新規代入したり) しているので、「恐らくループ内で画面なりファイルなりに出力している部分があって、それを省略している」んだろうと思ってましたから、単純にワタシはフラグをつけていっただけです。別に 1 じゃなくても $n でも undef でもいいんです。exists を使ってるので「かつて、そのハッシュの key は定義されたことがあるか」というのをチェックしているだけです。ハッシュを使わないと (例えば配列を使ったりすると) 今まで定義したリストを総ざらいしてチェックさせないといけないので、ループの後半に行けば行くほど異様に時間がかかります。

例えば極端な例を挙げると、以下の配列で、

my @a = ('教えて!', '教えて!', '教えて!', '教えて!', '教えて!', 'goo');
my @b = ('教えて!', 'goo', 'OK', 'web', 'hello', 'world', 'good', 'morning');

@a と @b の要素をチェックするのに、上記のように @a に重複項目が沢山あった場合があったとして、

foreach my $a(@a){
:
:
foreach my $b(@b){ ... }
:
:
}

というループ構造を作ったとします。foreach my $a(@a){ ... } (以下、"外のループ" とする) のループブロック ( { と } とで囲まれた範囲をブロックといいます) が一度実行されるたびに、foreach my $b(@b){ ... } (以下、"内のループ" とする) のループ (ブロック内を 8 回ループする) が行われるのはわかりますよね。
外のループのブロック一度目に '教えて!' が比較対照となり、内のループのブロックが 8 回ループされます。外のループが二度目のループに入った時、比較対照が再度 '教えて!' なので、もう @b に何個あるのかの答え (1 個) はわかってるのにも関わらず、内のループが 8 回ループします。外のループのループが 6 回行われるので、内のループのブロック内部は、48 回実行されます。
あえて「既にチェックしたかどうか」を調べて、チェック済みなら内のループのブロックを通過させず、外のループを次に進めること…

# 重複チェック用テンポラリハッシュを生成
my %tmp = ();

# 外のループ (6 回実行される)
foreach my $a(@a){
# チェック済みかどうかの判別
next if exists $tmp{$a};

# どうせこれからチェックするのは確実なので、
# チェック済みをあらわすフラグ値を設定
# (別にチェック後でもいいが。。。)
$tmp{$a} = 1;

# 内のループ (8 回実行される)
foreach my $b(@b){ ... }
}

によって、内のループのブロック内部をトータルで 16 回しか実行されずに済みます。
なので重複がある場合は、こういう手段を使えば、内のループの処理回数や処理速度を節約できます。

ワタシが質問の意味を根本的に誤って解釈していたので、「重複がいくつかある可能性が高い」という場合に、こういう方策が使えますが、逆に「重複が殆どない可能性が高い」場合には、こういう方法もネックになる可能性もありますから、それは実データがどうなっているのかを理解されている場合に使われるといいと思います。

で、長々と説明してしまったので結論にいきますがこういったケース (文字列の数を配列内部からチェックする場合) には、配列を一旦ソートして、どっちの文字が文字 (コード) 的に上位 (例えば昇順ソートなら A は B より下) なのかを見たほうが早いです。なぜかというと、ソートした配列同士を比較する際、外のループが "XYZ" なのに、内のループでの比較対照が "ABC" であれば、違うのは当然の事、「かけ離れてすぎて比較する事自体が無駄」です。配列がソートされているので、内のループの先頭要素が "ABC" だったとして、次の要素が "DDD" だったとしたら、"XYZ" と比較させるには "DDD" から調べていったほうが上記無駄を省いているぶん、「まだ処理は早い」でしょう。
仮に内のループの配列要素の末尾から 3 番目ぐらいの要素が "XXX" だった場合 (比較対照が近似値だった場合)、ソートされている事を考えると、次の要素が "XYZ" かもしれないという期待が持てます。なら、末尾 3 番目から末尾 "XYZ" を超えない範囲を調べる (超えたら調べ終わる) という方法を取り、内のループを「最小のループ回数」で調べるという方法を使えば、格段に処理が早くなります。
これを一般的に「近似アルゴリズム」と呼びます。

---
# 両配列をソートする
@hairetsu1 = sort @hairetsu1;
@hairetsu2 = sort @hairetsu2;

# 外のループの前回合計値を求めた比較対照文字列を格納する変数を宣言
my $last;

# 合計値を格納する変数
my $n = 0;

# 前回合計値を格納する変数
my $lastn = 0;

# 外と内のループを複合する (外のループ用添字 $i, 内のループ用添字 $j)
# ブロック終了後の実行式はあえて書かない
for(my $i = 0, my $j = 0; $i < @hairetsu1; ){

# 今回の比較値が前回の比較値と同じだったら、調べる必要がないので
# 画面に出力後、次の比較値を取り出す
if($hairetsu1[$i] eq $last){
output($last, $lastn);
$i++;
next;
}

# 比較対照同士を、文字列的にどちらが上位かを調べる
# 同じなら 0、左辺が大きければ +1、右辺が大きければ -1 になる
my $diff = $hairetsu1[$i] cmp $hairetsu2[$j];

unless($diff){
# 同じだった場合の処理

# 合計値に加算
$n++;

# 添字加算し、内のループを次の比較値に移す
$j++;

# この時、内のループの要素数を超えた場合はこれ以上比較する対象がないので
# 画面に出力後、全ての比較処理を終了
# (外のループがまだ残ってる可能性があるので、画面出力用変数代入をして続ける)
if($j >= @hairetsu2){

# 今回の結果をひとまず出力
output($hairetsu1[$i], $n);

# 次のチェック値は今後チェックしないので、出力用に代入

# 現在の結果
$lastn = $n;

# 現在のチェック文字列
$last = $hairetsu1[$i];
}
}elsif($diff == 1){
# 左辺が大きかった場合の処理 (内のループが次に進みます)

# 右辺 (内のループ) は次の要素を比較するように内のループを次に進める
$j++;
}else{
# 右辺が大きかった場合の処理 (外のループが次に進みます)

# 右辺が大きくなったという事は、内のループを進める必要がないので、
# これ以上の合計加算処理がない。なので画面に出力
output($hairetsu1[$i], $n);

# 次のチェック値が今回と同じだった場合用に、"前回合計値" として、
# 現在の結果を $lastn に代入
$lastn = $n;

# 次のチェック値の合計をリセット
$n = 0;

# 次のチェック値と同じかを調べる為に、"前回対象文字列" を代入
$last = $hairetsu1[$i];

# 外のループを次に進める
$i++;
}
}

# (文字列, 合計数) を受けて画面上に出力するサブルーチン
sub output{
my($val, $sum) = @_;

# 別にファイルに出力しようが画面上に出そうがは自由なので、とりあえず
# 画面に出してみてます。
print $val.' は '.$sum.' 個ありました'."\n";
}
---

…ちょっとサンプリングしてみましたが、"仕様先行型" じゃなくて、"発展型" でコーディングしてその後コメントをつけたので、完全動作かどうかのテストはしてません。でもじっくりコードを追ってもらえればわかると思いますが、比較回数は「必要最小限」に抑えられているので、無駄なループ、無駄な比較が行われないようになってます。コメントを参考にしてこのコードを追ってみて、「近似アルゴリズム」の原理を研究して、お手元の環境に一番適した方法にカスタマイズし、動作確認してみてください。原理研究には十分役立つサンプルに仕上げられたかなと思います。

ちなみに、配列の順序通りに合計個数を表示したかったら、sort の際に配列のソートした後の順をインデックスとして別配列に順番で並べ、出力はバッファリング (他の配列に蓄えるとか) してインデックスに合わせて並べ替えて出力するようにすればいいと思います。上記 output サブルーチンをカスタマイズするとか、sort をカスタマイズ (自分で、数あるソートアルゴリズムのどれかを用いて、sort 結果と順番のインデックスを出す関数を作ったほうがいいと思います) すれば、そういう事も容易に行えます。

また、比較させるための配列が数多いとの事ですが (1000 配列もあるなら、何時間もかかってませんか?) その配列全体を、ループさせるためのループ構造を上記のチェック機構の上位につくらなければいけません。
それを実現するために、@hairetsu1 とか @hairetsu2 とかの変数を新たに作るのではなく、リファレンス (ハードリファレンス) や無名配列を用いる方法を知っておいたほうがいいかもしれません。

---
@hairetsu = (
['I', 'am', 'a', 'Japanese', 'Programmer'],
['You', 'are', 'an', 'American', 'Programmer'],
['He', 'is', 'a', 'Korean', 'Programmer']
);

print $hairetsu[2][3]; # 結果は Korean
---
@tmpA = ('I', 'am', 'a', 'Japanese', 'Programmer');
@tmpB = ('You', 'are', 'an', 'American', 'Programmer');
@tmpC = ('He', 'is', 'a', 'Korean', 'Programmer');
@hairetsu = (\@tmpA, \@tmpB, \@tmpC);

print $hairetsu[1][2]; # 結果は an
---

このような方法を用いれば

@allArray = (\@hairetsu1, \@hairetsu2, \@hairetsu3, .... \@hairetsu1000);
for(my $subscript = 0; $subscript < @allArray; $subscript++){ ... }

で、for ブロック内で一回目は、$allArray[$subscript] が @hairetsu1 の実体を指し、$allArray[$subscript + 1] が @hairetsu2 の実体を指します。
この方法は中級者レベルだと思うので、「はじめての~」系には載ってないかも知れませんが、知っておいて損は絶対にないです。


以上、超長くなりましたが、回答とアドバイス、ご理解いただけましたでしょうか。
# 自己最長回答間違いなし。

#1 の nipotan です。

> 「=~」「==」「eq」いずれも同じと思っていました。

これらの違いを正確に理解しないと、根本的に手を加えるたびに脳内に未曾有の混乱を招くだけです。
=~ は左辺スカラーを対象にパターンマッチングや置換に使う (正規表現)
== は左右の値が数値的に等しいかを比較する比較演算子 * (01 == 1) は True *
eq は左右の値が文字列的に等しいかを比較する比較演算子 * ("01" eq "1") は False *
基本なので「はじめての~」系の本をお読みになって理解を深めたほうがいいと思います...続きを読む

QExcelの並び替えで、日付、時間、項目Bの順で並び替え

Excelの並び替えで、日付、時間、項目Bの順で並び替え
項目Aに特定の文字が入っていた場合は、優先的に一番最後にまわしたいのですが
どのように並び替え条件を指定すればいいのでしょうか?
※一番最後にまわすときも、日付、時間の順にしたいです。

■並び替えルール
日付、時間は昇順
項目Aは、海の人は最後に回す
項目Bは電話、メールの順(ユーザー設定済)

日付時間項目A項目B
1/110:00山電話
1/19:00山メール
1/112:00海電話
1/111:00海電話
1/18:00山メール

↓一発で下の順に並び替えたいのです。

日付時間項目A項目B
1/110:00山電話
1/18:00山メール
1/19:00山メール
1/111:00海電話
1/112:00海電話

Aベストアンサー

日付は最優先でその後は山、海の順、電話、メールの順のようですね。それぞれの項目に重みを付けて数値に置き換えます。それをもとに並び替えをすればよいでしょう。
例えば1行目は項目名としてE1セルには並び替えとでも文字を入力し、E2セルには次の式を入力し、下方にオートフィルドラッグします。

=IF(A2="","",A2+IF(C2="山",0.1,0.2)+IF(D2="電話",0.01,0.02)+B2*0.001)

E列の表示形式は標準にします。

次にA1セルからE列の最後の行までを範囲として選択したのちに、「並べ替えとフィルタ」から「ユーザー設定の並べ替え」を選択し、表示の画面で最優先されるキーに「並べ替え」とし「昇順」にしてOKすればよいでしょう。

QVBAで表作成中解らないことだらけ・・・ひとつずつ教えてください。

ブックの種類
入力フォーム→日付を設定するフォーム画面です。
book→予め出来ている表(B5・B7・B9・B10・I5はタイトル?になります)
   B  I   L ・・・
4         日付・・・
5 商品名 コード 曜日・・・
6 商品名 コード 数値・・・
7   小計    数値・・・
8 商品名 コード 数値・・・
9   小計    数値・・・
10  合計    数値・・・
入力データ→日付(曜日)、区分、商品名、商品数、コードが表になっています。

まず入力フォームで日付をセットします。
次にbookに入力フォームで入力した日付から1ヶ月間を表示させます。
(1) 日付設定表に設定日付をキーにして入力データブックより検索
(2) 検索日付が一致すれば、該当商品名、コード、区分、商品数等を取得
(3) 区分:1の場合は、該当日付の下の6行に、区分:2の場合は、8行に設定(同一商品の場合は加算)
但し、新しい商品の場合は行を追加→ 区分:1の場合は6行以降に、区分:2)の場合は8行以降に追加する
(4)区分ごとの小計を表示
(5)合計を表示
(6)bookのみ処理した日付と時間で保存
(7)入力データのブックを閉じる。

出来ているところは日付を貼り付けるまでは教えてもらいながらですができています。

明日中とのことなのでよろしくお願いします。

ブックの種類
入力フォーム→日付を設定するフォーム画面です。
book→予め出来ている表(B5・B7・B9・B10・I5はタイトル?になります)
   B  I   L ・・・
4         日付・・・
5 商品名 コード 曜日・・・
6 商品名 コード 数値・・・
7   小計    数値・・・
8 商品名 コード 数値・・・
9   小計    数値・・・
10  合計    数値・・・
入力データ→日付(曜日)、区分、商品名、商品数、コードが表になっています。

まず...続きを読む

Aベストアンサー

引き続き
不具合等はあるかも知れませんが、
以下のマクロを追加して、試してみてください。

Private Sub CommandButton1_Click()

  '一番最後に追加してください
  '商品情報の編集
  Call Edit_Shouhin(wSh2)'←追加
End Sub

'商品情報の編集
Sub Edit_Shouhin(wSh2 As Worksheet)
  Dim wC     As Integer
  Dim mC     As Integer
  Dim wDate    As String
  Dim hNm     As String
  Dim hCd     As String
  Dim hKbn    As String
  Dim hSu     As Integer
  Dim sTot1    As Integer
  Dim sTot2    As Integer
  Dim aSum    As Integer
  Dim Kbn1    As Integer
  Dim Kbn2    As Integer
  Dim wI     As Integer
  Dim fflg    As Boolean
  Dim wSu     As Integer
  '
  sTot1 = 7: sTot2 = 9: aSum = 10
  Kbn1 = 6: Kbn2 = 8
  With wSh2
    mC = .Cells(5, 12).End(xlToRight).Column
    For wC = 12 To mC
      wDate = wSh2.Cells(4, wC)
      '商品情報取得
      Call Get_HinData(wDate, hNm, hCd, hKbn, hSu)
      Select Case hKbn
        Case "1"  '区分1
          If .Cells(6, "B") = "" Then
            .Cells(6, "B") = hNm      '商品名
            .Cells(6, "I") = hCd      '商品コード
            .Cells(6, wC) = hSu       '数量
          Else
            fflg = False
            For wI = 6 To Kbn1
              If .Cells(wI, "B") = hNm Then
                .Cells(wI, wC) = hSu  '数量
                fflg = True
                Exit For
              End If
            Next
            If fflg = False Then
              .Rows(sTot1).Insert Shift:=xlDown
              .Cells(sTot1, "B") = hNm  '商品名
              .Cells(sTot1, "I") = hCd  '商品コード
              .Cells(sTot1, wC) = hSu   '数量
              Kbn1 = Kbn1 + 1
              Kbn2 = Kbn2 + 1
              sTot1 = sTot1 + 1
              sTot2 = sTot2 + 1
              aSum = aSum + 1
            End If
          End If
        Case "2"  '区分2
          If .Cells(Kbn1 + 2, "B") = "" Then
            .Cells(Kbn1 + 2, "B") = hNm   '商品名
            .Cells(Kbn1 + 2, "I") = hCd   '商品コード
            .Cells(Kbn1 + 2, wC) = hSu   '数量
          Else
            For wI = Kbn1 + 2 To Kbn2
              If .Cells(wI, "B") = hNm Then
                .Cells(wI, wC) = hSu  '数量
                fflg = True
                Exit For
              End If
            Next
            If fflg = False Then
              .Rows(sTot2).Insert Shift:=xlDown
              .Cells(sTot2, "B") = hNm  '商品名
              .Cells(sTot2, "I") = hCd  '商品コード
              .Cells(sTot2, wC) = hSu   '数量
              Kbn2 = Kbn2 + 1
              sTot2 = sTot2 + 1
              aSum = aSum + 1
            End If
          End If
      End Select
    Next
    '
    '小計設定(区分1)
    For wC = 12 To mC
      wSu = 0
      For wI = 6 To Kbn1
        wSu = wSu + .Cells(wI, wC)
      Next
      .Cells(sTot1, wC) = wSu
    Next
    '小計設定(区分2)
    For wC = 12 To mC
      wSu = 0
      For wI = Kbn1 + 2 To Kbn2
        wSu = wSu + .Cells(wI, wC)
      Next
      .Cells(sTot2, wC) = wSu
    Next
    '合計設定
    For wC = 12 To mC
      wSu = .Cells(sTot1, wC) + .Cells(sTot2, wC)
      .Cells(aSum, wC) = wSu
    Next
  End With
End Sub
'商品情報取得
Sub Get_HinData(wDate As String, hNm As String, hCd As String, hKbn As String, hSu As Integer)
  Dim wData    As Worksheet
  Dim wI     As Integer
  '
  Set wData = Workbooks("入力データ.xls").Worksheets("Sheet2") '←実際のブック名とシート名に変更
  With wData
    mR = .Cells(Rows.Count, "B").End(xlUp).Row
    For wI = 3 To mR
      If .Cells(wI, "B") = wDate Then     '←ここで両方の日付を確認してください
        hNm = .Cells(wI, "T")
        hCd = .Cells(wI, "BA")
        hKbn = .Cells(wI, "M")
        hSu = .Cells(wI, "AQ")
        Exit For
      End If
    Next
  End With
End Sub

引き続き
不具合等はあるかも知れませんが、
以下のマクロを追加して、試してみてください。

Private Sub CommandButton1_Click()

  '一番最後に追加してください
  '商品情報の編集
  Call Edit_Shouhin(wSh2)'←追加
End Sub

'商品情報の編集
Sub Edit_Shouhin(wSh2 As Worksheet)
  Dim wC     As Integer
  Dim mC     As Integer
  Dim wDate    As String
  Dim hNm     As String
  Dim hCd     As String
  Dim hKbn    As String
  D...続きを読む


人気Q&Aランキング