Excel VBA質問スレ Part7 at TECH
[2ch|▼Menu]
[前50を表示]
600:デフォルトの名無しさん
08/07/29 12:05:21
はい。

601:デフォルトの名無しさん
08/07/29 12:42:22
どうしればいいのでしょうか
教えてください

602:デフォルトの名無しさん
08/07/29 13:36:48
全てのひらがなのリストを用意し、入力された文字がその中に見つかるかどうか判定すれば宜しいのではないかと。

603:デフォルトの名無しさん
08/07/29 14:22:43
そんな無駄で面倒なことしなくても、文字コード判定すれば一目瞭然かと

604:デフォルトの名無しさん
08/07/29 16:30:33
>文字コード判定

こいつを具体的に。

605:デフォルトの名無しさん
08/07/29 20:05:58
VBAからSASを操る事は可能でしょうか。
もし可能だったら、どんな感じで行えるのかを教えてくださいませ。

606:デフォルトの名無しさん
08/07/29 20:38:51
> VBAからSASを操る事は可能でしょうか。
可能です

> もし可能だったら、どんな感じで行えるのかを教えてくださいませ。
>>1★3

607:デフォルトの名無しさん
08/07/29 22:06:22
ありがとうございました。


608:デフォルトの名無しさん
08/07/29 22:41:39
>>604
平仮名の文字コード知るには

Cells(1, 1).Value = Asc("あ") ' -32096 を返す

609:デフォルトの名無しさん
08/07/29 22:44:03
グラフを描くとき、データ範囲設定において、
A1〜A12のデータがあり、A1〜A6、空白データ、A7〜A12と設定してグラフを描きたいのですが、
空白データの設定がわかりません。
空白データA1000〜A1010を設定して、Unionで範囲結合しても駄目でした。

できる限りシートのデータ位置は移動させたくありません。
何かよい方法がありましたら教えてください。

610:デフォルトの名無しさん
08/07/29 22:48:11
>>608
で、それが>602よりも無駄でもなく面倒でもないと?

611:デフォルトの名無しさん
08/07/29 22:49:46
>>609
見せないダミーのセルに空白データを抜いてコピーするんじゃダメ?

612:デフォルトの名無しさん
08/07/29 23:00:27
>>602
もしアルファベットやらカタカナやらが入力されても漢字と判定するって事か
どういう入力があるのか知らんけど

613:デフォルトの名無しさん
08/07/29 23:11:06
>>610
-32096から-32015の値を探せば良いだけ
直接文字列の"あ"とか探すよりも効率的
意味わからないかな?

614:デフォルトの名無しさん
08/07/29 23:47:04
>>611
すでにデータが入っていて、他関数からも使うので位置は動かしたくないのです。

615:デフォルトの名無しさん
08/07/30 02:37:30
コードを手動でエクスポートするのが面倒なので、コードをすべてエクスポートしてdoxygen
するコードを書いてみました。
要はイミディエイトウインドウの内容をクリアして、Enterキーを送ってイミディエイトウインドウ
でshellコマンドを実行したいんですが、クリアする処理をすると、コマンドが送られた後
クリアされてしまいます。クリアする処理を省けば問題ないのですが、できれば出力過程も
イミディエイトウインドウに出力したいのです。気分的に。
どなたか同じような事やったことある方いませんか?

Sub prcExportVBComponents()
Set oVBComponents = Application.VBE.ActiveVBProject.VBComponents
Set oWin = Application.VBE.Windows
Set oCodePane = Application.VBE.ActiveCodePane

' prcClearImmediateWindow ' イミディエイトウインドウをクリア
' oWin.Item("イミディエイト").WindowState = vbext_ws_Normal
' oWin.Item("イミディエイト").SetFocus
' SendKeys "^a"
' SendKeys "{Del}"
'処理

Debug.Print "shell " & Chr(34) & strComponentPath & "bld.bat" & Chr(34) ' doxygenを実行
'前の行に戻ってEnter
oWin.Item("イミディエイト").SetFocus
SendKeys "{Left}"
SendKeys "{Enter}"
End Sub

616:デフォルトの名無しさん
08/07/30 07:39:21
>>615
わざわざイミディエイトウィンドウで実行しなくてもいいんじゃないの?
つまり、End Subの前の3行(コメントも入れて4行)を

Shell strComponentPath & "bld.bat"

に置き換える。

617:デフォルトの名無しさん
08/07/31 21:46:16
ブックを変更して、ファイルを閉じようとしたり、エクセルを終了
させようとすると、
「変更を保存しますか?」
とメッセージが出力されます。
ここで、「はい」、「いいえ」、「キャンセル」のどれが
選択されたかを取得する方法ってありますか?

618:デフォルトの名無しさん
08/08/01 00:26:32
あります

619:デフォルトの名無しさん
08/08/01 00:41:10
ちょっと前からこのスレ見てるけど、やけに意地悪なやつがいるな
たぶん同一人物だろう

620:デフォルトの名無しさん
08/08/01 00:45:00
いいえ

621:デフォルトの名無しさん
08/08/01 07:50:45
>>619
馬鹿?

622:デフォルトの名無しさん
08/08/01 09:16:09
わざわざ質問に答えてて充分親切だと思うよ。
方法の詳細を知りたいなら、ちゃんと質問しない方が悪い。

623:デフォルトの名無しさん
08/08/01 09:32:49
>>617
return value

624:デフォルトの名無しさん
08/08/01 15:02:50
名簿にオートフィルタを使い、名前の列(B列)で抽出された可視セルを配列に格納するプログラムを作ろうとしています。
現在、可視セルを配列に格納する部分で躓いています。
Dim i As Long
Dim hairetu() As String
Dim kasi As Long

kasi = Range("B2", Range("B2").End(xlDown)).SpecialCells(xlCellTypeVisible).Count
ReDim hairetu(kasi - 1)

For i = 0 To kasi - 1
hairetu(i) = Range("B2:B100").SpecialCells(xlCellTypeVisible).Value
Next

修正すべき箇所や効率的な方法がありましたら教えてください。

625:デフォルトの名無しさん
08/08/01 15:10:23
cells(1,1).end(xldown)
で、可視セルを1段ずつ下げて行くとか?

626:デフォルトの名無しさん
08/08/01 17:41:24
グラフで折れ線を描くとき、間にデータがないと線でつないでくれません。
ツール、オプション、グラフで線を補完すると線は引かれました。

ここで質問です。
間を補完したい項目、補完したくない項目があります。
ある項目のみ補完する方法があれば教えてください(VBAでも可)


627:デフォルトの名無しさん
08/08/01 20:48:21
データを線形補間して、別のシートに出力、グラフ生成

628:y
08/08/01 22:22:26
>>624

コードを見る限り、SpecialCells(xlCellTypeVisible)が
可視セルのコレクションを返す、ということは分かっておられると思います。
コレクションに何個のセルが含まれているかをCountプロパティで取得し、
配列の要素数を確定するところまでは、きちんとできています。

問題は、最後のForループです。今の場合は、可視セルのコレクションの
個々の要素の値を配列に格納したいわけなので、
Forループではなく、For Each ループを使うのが妥当です。
(あらかじめ、コレクションの要素を受けるための変数c as Variantを宣言しておいてください)

i=0
For Each c in Range("B2", Range("B2").End(xlDown)).SpecialCells(xlCellTypeVisible)
 hairetu(i) = c.Value
 i=i+1
Next



629:y
08/08/01 22:41:09
>>626

まずは「ツール、オプション、グラフで線を補完」の状態にしておきます。
これで基本的に補完される状態になります。

次に、補完したくない要素について、線の色を背景色と同じにし、見えなくします。
VBAで表現すると次のようになります。
ActiveChart.SeriesCollection(1).Points(4).Border.Colorindex=2
(系列1の4番目の要素の線の色を白にする)
プロットエリアの背景色が白なら、こうすることで見えなくなります。

この操作をマウスでやってみて、「マクロの記録」を
してみると分かりやすいと思います。

630:y
08/08/01 22:53:57
>>614

>>611の言いたいのは、もとのデータを移動させることではなく、
もとのデータのコピーを別の場所に貼り付けて、
そのコピーをグラフのデータとすればいいのではないか、
ということだと思います。
私も、それ以外方法が思いつきません。

別シートのA1:A6に、元シートのA1:A6を、
A8:A13に、元シートのA7:A12を、
それぞれ「リンク貼り付け」します。

そして、別シートのA1:A13をグラフのデータとします。
「リンク貼り付け」しておけば、元シートのA1:A12が変化しても
即座に反映されます。


>>615
すごい面白そうですが、私はやったことがありません。

631:デフォルトの名無しさん
08/08/01 23:50:44
コレクションのすべてに命令を掛けるループは for each が妥当だとは思うんだけど、
for でcountして回すのと、for eachでコレクションにループ掛けるのではどっちがスマートなんだろ。

今、実測出来る場所じゃないんだけど、誰か測定した事ある人いますか?


632:デフォルトの名無しさん
08/08/02 00:05:45
>>631
ほとんどかわらないみたい
URLリンク(officetanaka.net)

633:デフォルトの名無しさん
08/08/02 00:20:28
何も事情がないかぎりFor Each使ったほうが分かりやすい。

634:デフォルトの名無しさん
08/08/02 13:46:15
値渡しとか参照渡しするくらいなら
はじめからPublicで定義しといたほうがいいとおもうのはおれだけ?

635:デフォルトの名無しさん
08/08/02 14:03:54
Publicはできるだけ少なくするのが基本 なくせるならないほうがいい

636:デフォルトの名無しさん
08/08/02 14:09:22
UserForm に Application.GetOpenFilename でファイルを開くダイアログを
使ってファイルを開いた後に、UserFormにファイルをドロップできるように
なってしまったんですが、私だけですか?

637:y
08/08/02 14:16:59
>>631

基本>>633ですが、たしかに事情によっては、
コレクション対象であってもForループの方がスマートな場合もあります。
たとえば、コレクションのすべての要素を配列に格納したい場合、

i = 0
For Each tmp In myCollection
 ary(i) = tmp
 i = i + 1
Next

とすると、配列添字カウンタ変数iと、アイテム取り出し変数tmp
の2つがどうしても必要ですが、Forループなら添字カウンタ変数だけで
済みますよね。

For i = 0 To myCollection.Count - 1
 ary(i) = myCollection.Item(i + 1)
Next

カウンタ変数の加算が、For構文の中に組み込まれているのも利点で、
できるだけDo Loop ステートメントではなくFor ステートメントを使うことを
好む方も、たいていそれが理由だとか。

でも速度的には、下の例はループのたびに補正演算が入るので、ほんのちょっと
遅くなってしまうかも。


638:デフォルトの名無しさん
08/08/02 16:49:03
僕はいつもこうしてます。気分的なもので。
こっちのほうが早いような気がしてます。

lngCnt = myCollection.Count
For i = 0 To lngCnt - 1
 ary(i) = myCollection.Item(i + 1)
Next

639:デフォルトの名無しさん
08/08/02 16:51:36
VBAで大量のコレクションをループすると非常に遅くなりますよね

640:デフォルトの名無しさん
08/08/02 17:55:31
速度は気にするべきじゃない。
なんにせよ、パフォーマンスは計らないとわからないという一面もあるし。
最初はアホなコーディングさえしなければおk。

641:y
08/08/02 18:31:11
アホなコーディングといえば、初心者の頃の私は>>634をさらにつきつめたような
考えを持っていて、ある日「どの関数でもループにiを使うなら、iをパブリック変数に
しておけばいいじゃない!」とひらめいたのです。そしてその方法で2つぐらい
モジュールを書いて、「これはどんな解説書にも載っていない画期的な方法だ!」と
思い込んでいました。


642:デフォルトの名無しさん
08/08/02 18:35:13
確かに画期的だね

643:デフォルトの名無しさん
08/08/02 18:52:55
VBAはブロック単位で変数が初期化されるわけじゃないから、
初期化処理を書かないまま特定の処理部分をループにしたりすると、
前回の内容がそのまま流れてきたりしてしまうんだよなあ。

644:デフォルトの名無しさん
08/08/02 19:00:17
static i が良く分かりません。

関数1で使った変数の続きを関数2で利用する時に、
いったん、ストック用の変数に入れて、関数2の時に呼び出してる人がいたので、
staticで続ければ良いんじゃないですか?

と言ったら、無知は黙ってろ。と言われました。
staticは関数間で解放されない変数と記憶していたのですが、間違ってますでしょうか。

645:デフォルトの名無しさん
08/08/02 19:31:37
エクセルからワードに差し込むように
エクセルファイル(データ)→エクセルファイル(伝票書式)に差し込みたいけど
伝票書式側のファイルにVBAや関数組んで引っ張ったほうがいいのかな?

差込ボタンを押したら
・(データ)ファイルの一番下の行をコピー
・(伝票)ファイルの適当なところに貼り付け
・でそこをセル参照
・↑↓ボタンを押したら(データ)ファイルのデータの1行上・下をコピー、以下同

こんな感じでしょうか?
もっといい関数とやらはあるのでしょうか?
会社のPCはアクセス無いから大変だ・・

646:617
08/08/02 20:18:35
>>623

すいません。もう少し詳しく教えて頂けませんか?

647:デフォルトの名無しさん
08/08/02 20:39:25
>>645
>・↑↓ボタンを押したら(データ)ファイルのデータの1行上・下をコピー
押したタイミングで命令をするならイベントハンドラの考え方になるね。

SheetSelectionChangeイベントが良いかな。
右左をとれないようにして、keydownで設定するのも良いかも。

ここまで書いたんだけど、どんな制御にしたいかイメージが難しいです。
すいません。

648:y
08/08/02 21:16:58
>>642 >>643
その後、ループの中から別関数を呼び出し、呼び出し先関数でもループを用いる形が出てきて、
同じPublic iを使い回していたその画期的なシステムは、完全に機能不全に陥りました。

>>645
いろいろなやり方があると思います。私はむしろデータブック側に、
任意のデータを取り出すためのユーザー定義関数を実装し、
伝票書式ブック側から参照設定するやり方をよく用います。
たとえば、データの主キーが「伝票番号」である場合、
「伝票番号」を渡すとその伝票の売上日を返す関数UriageDate(dNum)、
売り先を返す関数Urisaki(dNum)、金額を返す関数Kingaku(dNum)、
などをデータブック側に定義しておきます。

そうして伝票書式ブックから参照設定でそれらの関数を
利用できるようにすれば、任意のセルにその関数を入れるだけで、
お好みのデータを取り出すことができます。
たとえば、伝票書式ブックのA1が伝票番号のセルだとすると、あとは任意のセルに
=UriageDate(A1)、=Urisaki(A1)、=Kingaku(A1)
という数式を埋め込んでおけば、A1の伝票番号を変えるだけで、
即座にこれらの関数が適切なデータを返してくれます。

伝票書式ブック側にVBAモジュールを実装し、その中で「Cells(3,4)に売り先を書き込む、Cells(4,10)に金額を書き込む」
とやっていると、伝票書式のデザインを変更したいときに柔軟に対応できませんが、
このやり方なら、数式を埋め込むセルを変えるだけで済みます。
また、参照設定さえすれば、さらに別のブックからもこれらの関数を利用できます。


649:デフォルトの名無しさん
08/08/02 21:28:15
機能不全になる前に気づけよw

650:デフォルトの名無しさん
08/08/02 21:36:20
他人に迷惑かけない限り別にいいじゃない。
641じゃないけど実際に痛い目にあうとよく覚える。

651:デフォルトの名無しさん
08/08/02 21:38:18
カスタムシート関数の場合は共有設定でも見られるのがいい

652:y
08/08/02 21:46:37
>>649
機能不全の理由が分かるまで3日ぐらいかかりましたw
初めての頃はまずそんなもんです。

>>644
間違っているかどうかは、文章だけではよくわかりません。
関数1を呼び出す関数が、関数2以外にも複数ある場合は、
それら別の関数が、関数1の中の Static i をいじる可能性があります。
本来、Static変数はそういう使い方をされるためにあるのですが、
やはり場合に応じて、いじられても良い時と、いじられたら困る時とがあります。
後者の場合は、とりあえず現在の値をどこかにストックしておく必要が生じます。


653:645
08/08/02 22:04:31
ユーザー定義関数か・・・ちょっとやってみよう

654:デフォルトの名無しさん
08/08/02 22:33:09
ちなみにユーザ定義のシート関数のパフォーマンスなら↓に載ってた。
まあ、正確だとはいえないが、VBAが決して遅くないことがわかる。
URLリンク(www.spreadsheethell.com)

655:デフォルトの名無しさん
08/08/02 23:38:08
C#圧倒的だな

656:デフォルトの名無しさん
08/08/03 00:02:13
そうね 圧倒的に遅い

657:デフォルトの名無しさん
08/08/03 00:12:51
マクロでコピー、貼り付けを記録すると
Range("A3").Select
Selection.Copy
Range("C3").Select
ActiveSheet.Paste
こうなりますが、汎用性を高めるために
  i=Activecell.row
  Cells(i,1).Select
Selection.Copy
  Cells(i,3).Select
ActiveSheet.Paste
としました。
でもコピー貼り付けが多くなったり、列入れ替えがあると列の番号の変更が大変です。
シートの上端行を名前で定義した場合、マクロで名前を使うにはどうすればいいのでしょう?
Cells(i,"顧客名").Select のように使えたらいいのですが・・・

658:デフォルトの名無しさん
08/08/03 00:15:53
Range("C3") = Range("A3") でおっけ

659:657
08/08/03 00:24:34
A3をC3にコピーするだけじゃなく
汎用性を高めるために
選択セルの行の 1列目を3列目にコピーするようにしたいのです。(実際は別ブックへ)

660:デフォルトの名無しさん
08/08/03 00:45:57
do until cells(1,j).value = "顧客名"
j = j + 1
loop

cells(i,j).copy

とか?

661:デフォルトの名無しさん
08/08/03 00:47:13
普通に[1:1].Find("顧客名").Column??

662:657
08/08/03 06:52:56
i = ActiveCell.Row
j = [1:1].Find("顧客名").Column

Cells(i, j).Select
Selection.Copy
Range("C3").Select
ActiveSheet.Paste

でうまくいきました。ありがとうございます。

663:デフォルトの名無しさん
08/08/03 22:25:28
部門テーブル
主キー 
01)部門CD  数値 4桁
02)部門カナ 文字 10桁
03)部門名  文字 20桁
04)部門略称 文字 6桁
05)作成日  日付 --桁
06)作成時間 時間 --桁
07)作成端末 数値 7桁
08)作成者ID 文字 10桁
09)更新日  日付 --桁
10)更新時間 時間 --桁
11)更新端末 数値 7桁 
12)更新者ID 文字 10桁

部門CD,部門カナ    ,部門名      部門略称 作成日 作成時間  作成端末 作成者ID 更新日   更新時間 更新端末 更新者ID  
  1,エイギョウ    営業       営業    2002/09/01 00:00:00  80001 FUJI 2002/09/01 00:00:00 80001 FUJI   


664:デフォルトの名無しさん
08/08/03 22:28:16
おっと

665:デフォルトの名無しさん
08/08/03 22:53:52
663のを教えて。


666:デフォルトの名無しさん
08/08/03 23:00:13
富士通もとうとう日本語が喋れないのが標準になったか

667:626
08/08/04 03:41:16
>>629
>次に、補完したくない要素について、線の色を背景色と同じにし、見えなくします。
一部線が引かれているところがあり、そこは見えてもらわないと困るのです。

668:デフォルトの名無しさん
08/08/04 04:00:15
>>667
データを線形補間して、別のシートに出力、グラフ生成

669:デフォルトの名無しさん
08/08/04 07:55:36
Excelの機能には限界があるんだから、Excelでできない事は自分でやらないと

670:デフォルトの名無しさん
08/08/04 08:07:21
>>667
線全部じゃなくて、要らないところだけ背景と同色にすればいいだろ。

671:y
08/08/04 14:08:37
>>667

>>670でフォローしてくださっている通り、
線全部ではなく、一部分だけを背景と同色にできます。
>>629のコード例はそのつもりで書いたもので、
系列1の線の、4つ目の線分だけを見えなくします。
つまり、点1から点4までと、点5から最後の点までは
きちんとつながっている状態です。

手作業で(マウスで)試す場合は、ある線をクリックして、
さらにもう一度クリックしてみてください。
クリックされた線分だけがアクティブになるはずです。
その部分だけに、お好みの書式を適用できます。
その動作をマクロ記録すれば、VBAでどう表現するのか
分かりやすいと思います。

>>668でもいいと思います。


672:デフォルトの名無しさん
08/08/04 14:14:19
マクロ記録はAlt, T, M, Rと覚えてしまったら楽。

673:デフォルトの名無しさん
08/08/04 15:39:51
一つの変数を複数のユーザーフォームで使いまわす方法ありますかね?

674:デフォルトの名無しさん
08/08/04 16:15:19
>>672
やめてくれ。マクロ記録するたびにあのボーカルの顔が浮かんじまうw

>>673
「使いまわす」を詳しく。

675:デフォルトの名無しさん
08/08/04 21:21:01
久しぶりにマクロ組んで保存して使おうと思ったら・・・・
マクロ有効形式でなければ保存受け付けないだの
セキュリティレベルの警告も出ないまま無効だの
ファイルが安全な場所になきゃ有効にしてくれないだの


すげーむかついた
vista視ね

676:デフォルトの名無しさん
08/08/04 22:03:41
visuta厨涙目w

677:デフォルトの名無しさん
08/08/04 22:12:52
それWindows VistaだからじゃなくてOffice 2007だからだろ。

678:デフォルトの名無しさん
08/08/04 23:57:08
2007のリボンは本当にひどい。
慣れとか言う以前に、慣れても面倒。
クリック回数が増えただけですわ。

Alt+F8 , Alt+F11 で慣れてないとVBE環境もつらい・・。

679:デフォルトの名無しさん
08/08/05 00:27:38
他に選択肢ないのがつらいね
あぁ待てばいいだけか

680:デフォルトの名無しさん
08/08/05 09:51:05
質問です。現在、ユーザーフォームを.PrintFormを使い印刷しています。
このユーザーフォームは、
上側にボタンが横一列で並んでいて
中央にコメントボックス、
下側にラベル
という形になっています。

このユーザーフォームを、コメントボックスとラベルのみを印刷、
又は印刷時にボタンを非表示にする、ということは可能でしょうか?
もしできるのであればその方法を教えてください。お願いします。

681:デフォルトの名無しさん
08/08/05 10:23:10
>ボタンを非表示にする、

という事であれば、

userform1.button1.visible = false にすれば
非表示には出来る

682:デフォルトの名無しさん
08/08/05 11:29:34
セルに文字列があり、変数に取り込みメッセージの一部に使いたいのです。

しかしセルに改行が入っていると当然メッセージでも改行されます。
改行を取り除く方法があれば教えてください。

683:デフォルトの名無しさん
08/08/05 11:38:02
vbcrlfを探して取り除く。

684:デフォルトの名無しさん
08/08/05 17:13:22
Alt+Enterでのセル内改行はvbLfのみだぞ
.Value = "a" & vbCrLf & "b"
みたいにすれば、vbCrLf での改行も不可能では無いが
普通はvbCrLfを取り除いても意味無い

685:デフォルトの名無しさん
08/08/05 20:01:44
excelでデータベースのロジカルチェックを掛ける事を考えておりまして、
つきまして、プログラム構造、モジュール構造についてアドバイスを頂きたく投稿します。

ロジカルチェック自体は、200-300個あります。
今考えているのは、1つのモジュールに、private sub で200個のプログラムを書いておき、
1つの sub で200個のチェックプログラムを call しようと考えています。

そこで質問なのですが、1つのモジュールにたくさん詰める事は好ましくないのでしょうか。
保守を考えると、private sub A010010 のように、チェック番号をプログラム名にしておけば、
Ctrl+Fの検索で、見つけやすいかなぁ。と思っています。

皆様だったらば、どのように構築していくか等、アドバイスを頂ければ幸いです。
よろしくお願いします。

686:デフォルトの名無しさん
08/08/05 20:19:44
ストアド書いて、befor triggerにしろ

687:デフォルトの名無しさん
08/08/05 21:09:25
勉強不足で申し訳ありません。ストアドプロシージャは初めて聞きました。

データベースはSASで作成されているのですが、SASを使える人が少ない上、
教育に金が掛かる&SASライセンスが高い。と言う理由で、
なるべくコストの掛からない方向を考えている次第です。
統計解析を行うので、データベースをSASから変える事は難しいです。

イメージとしては、SASで作成されたデータセットを1つのブックに統合し、
その統合ファイル上でロジカルチェックを掛けられればと思っています。

当方、ACCESSやSQLの知識が無い為に、ストアドと言う単語も初めて聞いたのですが、
やはりEXCELのみで完結させるのは難しいでしょうか。

もし可能であれば、もう少し詳しく教えていただけますでしょうか。よろしくお願いします。
情報小出しのようになってしまい申し訳ありません。

688:デフォルトの名無しさん
08/08/05 21:28:12
>>687
長い目で見れば、弊社のような専門家にお任せいただくのが一番かと存じます。

689:デフォルトの名無しさん
08/08/05 21:30:04
難しい言い回しにしなくてもいいと思うよ
URLリンク(www005.upp.so-net.ne.jp)

690:y
08/08/05 21:38:27
>>685

最適な構造は、最終的にどういう運用をしたいのか
なるべく具体的にイメージすることで見えてきます。
細部の仕様も、その過程で決まっていきます。

・常に全種類のチェックが必要か
 →状況により、「前半のチェックは省略したい」などの要求が起こりえる場合
   →Call文のコメントアウトで対応?
   →スイッチUI実装?
     →チェックする項目のプリセットを保存できれば便利?

・エラーレポートはどうしたい?
 →Excelシートに出力
 →テキストファイルに出力

・修復ロジックも実装したい?

そのプロジェクトは一人で担当しているのですか?
もし何人かでやっているのであれば、上のような点を
協働者とも相談してみてください。


691:デフォルトの名無しさん
08/08/05 21:44:58
>>689
ありがとうございます。ただ、SASでステップは走らせません:(

すいません。私の質問の仕方が悪かったようです。

データベース、解析は一切関係無いとして、
1つのEXCELブック内にあるデータ同士の整合性をチェックするプログラムが200個あります。
この200個はどのように書いて行く、もしくは作成していくべきでしょうか。
個々に呼び出す必要はなく、必ず200個全てを走らせます。
1つの標準モジュールに200個羅列して行くべきか、モジュールを分割するべきか、
はたまたストアドを利用するか・・・。

ストアドプロシージャを調べてもEXCELと関連のあるページは見つけられませんでした。

本当に申し訳ありません・・・。

692:デフォルトの名無しさん
08/08/05 21:54:01
>>690
レスありがとうございます。
組み込んだロジカルチェックは必ず全部実行させます。

エラーレポートに関しては、後々処理が出来るように、別ファイルにダンプし、ログとして集積させます。
そして、レポートを発行する際に、管理番号でオートフィルタを掛け、
マクロでレポートの形にして、発行出来るようにする事を考えています。

プロジェクトとしては、これから提案して変えて行こうと思っている段階です。
その為には、具体的にロジカルチェックをEXCELのみで掛ける事が重要と思いまして、
質問をさせていただきました。


693:デフォルトの名無しさん
08/08/05 21:56:31
>>692
運用がわからんからなんとも言えんが、パフォーマンスなんかは問題にならんの?
# そして全く無視される>688w

694:デフォルトの名無しさん
08/08/05 22:03:04
>>693
private sub で200個を1つのモジュールに記載して、
呼び出し用の sub で200個を call する事は問題が無いのか、そこが気になっています。

そこまで多くのプログラムを1つのモジュールに書いた事がありません。
本当に動くのかも悩みの種です。

統合ファイルの内訳としては、その度に変わるので一概には言えないのですが、
平均すると25-30シートで、1つのシートに多くとも2000行程度なので、問題はなさそうです。



695:デフォルトの名無しさん
08/08/05 22:37:38
>>694
・Subではなくて、FunctionでBooleanを返したほうが良いのでは?
・一つのモジュールに入る大きさのコードなら、どれだけ書こうと全く問題がない(限界を超えたら
 実行時エラーとして教えてくれる)
・保守を考えるなら、第三者が見てわかりやすい関数名にしたほうが良い
・関数名には日本語が使えて、さらに日本語を使っても全く問題がないので、日本語を使った
 関数名にするというのも一つの手

696:デフォルトの名無しさん
08/08/05 22:51:41
>>695
レスありがとうございます。
functionのboolean戻りは良いですね。
booleanで返した時に、エラー項目を引っ張る際にもう1段踏まないと行けないのがつらそうですが、
何とか対処出来そうです。

やはりモジュールに限界はあるのですか・・・。でも実行時エラーが出るなら安心ですね。

実はチェックリストが存在していて、そのチェックリストを基にプログラムを組むので、
チェックNo.のコードを関数名にするのが良いと思いました。

アドバイスありがとうございます。


697:デフォルトの名無しさん
08/08/05 23:02:38
200ねえ…
そんな量じゃなければ、私ならインタフェース使ってクラス量産かな。
(なんせ200もクラスがあるとウザいので)
これなら処理を値として扱える。

698:デフォルトの名無しさん
08/08/05 23:05:49
>>697
ですよねぇ・・・。
一つ一つは小さい処理で、日時の整合性を確かめたりする程度なのですが、
何せ200-300、プロジェクトによってはもっと増える事もあるんですよね。
だから、作成者と保守者が別でもわかりやすいように、と色々考えてはいるのですが、
なかなか纏まらない感じです。

皆様、アドバイスありがとうございました。
2-3日、無い知恵絞って頑張ってみようと思います。

本当にありがとうございました。失礼します。

699:y
08/08/05 23:09:40
>>694

>private sub で200個を1つのモジュールに記載して、
>呼び出し用の sub で200個を call する事は問題が無いのか
私も、これ自体は問題ないように思います。
少し上のほうのレスに、再帰呼び出しの話題がありますが、
数百個ぐらいなら、たとえネスト呼び出ししても大丈夫です。
コードの長さについては、万が一どうしても収まらない事態になれば
別々の標準モジュールに分割してもいいでしょう。
その場合、各ロジックチェックはPublicスコープにする必要がありますが、それが
嫌であれば、クラスモジュールに書いてFriendスコープにしておく手もあります。
いずれにしても、取り返しのつかない結果になる心配はありません。
常に200のチェックを行い、カスタマイズの可能性も無いのであれば、
まず1つのモジュールに羅列しておくのがシンプルで良いかと。

>>695の >・Subではなくて、FunctionでBooleanを返したほうが良いのでは?
と同じことを考えていましたが、エラーログ出力部となるプロシージャをどのように
配置するかによって、2通りの構造が考えられます。
ロジカルチェックをFunctionで書いて、呼び出し元にエラーチェック結果を返し、
呼び出し元からエラーログ出力プロシージャを呼ぶのか、
あるいは、ロジカルチェックをSubで書いて、エラーが検出されたらそのSubから
エラーログ出力プロシージャを呼ぶのか。
単純に「エラーがあった、なかった」だけのレポートで済むのであれば、
Bool値を返すFunctionでいいと思いますが、「どのようなエラーなのか」まで
表現したい場合は、後者の方が都合がいいかもしれません。


700:デフォルトの名無しさん
08/08/05 23:12:36
COM経由で呼べる組み込み言語ってないだろうか。
適当にJScriptインタプリタ起動できたりしないのだろうか。厳しいかな。

701:デフォルトの名無しさん
08/08/05 23:31:26
ときどき 0& ってのを見るんだけど、これってどういう意味ですか?
If Len(buf) = 0& Then〜 みたいな感じです

702:デフォルトの名無しさん
08/08/05 23:37:33
Long型の0

703:デフォルトの名無しさん
08/08/05 23:38:51
ごめん うそ

704:デフォルトの名無しさん
08/08/05 23:45:50
>>700
Microsoft Script Control

705:デフォルトの名無しさん
08/08/06 00:27:14
>>704
thx!

706:デフォルトの名無しさん
08/08/06 11:07:42
範囲(行のみ下がる、列数data_nは同じ)が離れているセルの値を、その範囲だけ、二次元配列に格納したいです。

仮に範囲数が4つなら二次元配列は(4,data_n)

unionで範囲を結合しても3つまでしか結合できませんでした。

だから1つずつ範囲から値を配列に格納しようとしていますがうまくいきません。

どのように配列定義、範囲から二次元配列への格納をすればよいでしょうか?


707:y
08/08/06 18:02:38
>>706

>範囲数が4つなら、二次元配列(4, data_n)
という点から想像すると、それぞれの範囲は1行×data_n列のサイズになっている
ということですか?

まず配列の定義ですが、特に設定を変えない限り、配列の番号は0から始まるので、
(4, data_n) と定義すると、実際には 5 × (data_n + 1) 個分の配列が
準備されます。本当にそれでいいかどうか確認してください。

次に格納の仕方ですが、
>1つずつ範囲から値を配列に格納しようとしていますがうまくいきません。
この考え方でも大丈夫です。中途半端でも構わないので、
とりあえず書いたコードを貼ってみてください。


708:デフォルトの名無しさん
08/08/06 19:37:01
春日部市1-2-3のような文字列の数字部分のみ半角に変換する方法を探していたら
次のようなマクロを見つけました。

Sub MacroR()
Dim idx As Integer, trg As Range
 Set trg = ActiveSheet.Cells.SpecialCells(xlCellTypeConstants, xlTextValues)
 For idx = 0 To 9
  trg.Replace What:=Right(StrConv(Str(idx), vbWide), 1), Replacement:=Right(Str(idx), 1)
 Next
End Sub

ここでRight関数を使っているのは、Str関数だと先頭に符号が付くからですか?

これのReplaceの部分を
  trg.Replace What:=StrConv(CStr(idx), vbWide), Replacement:=idx
に変更すると同じ事が出来たのですが、これだと何か不都合が出たりしますか?

709:デフォルトの名無しさん
08/08/06 19:44:55
変数のスコープについて教えてください。
全ての標準モジュールで使用出来る範囲を付与するには、
どの部分に、どのように宣言したらよろしいのでしょうか。

710:y
08/08/06 20:06:42
>>708
あなたのコードの方が良いように思います。
ReplacementのところはCstr(idx)にするとより丁寧です。


711:y
08/08/06 20:11:16
>>709
付属のヘルプで、
「Public ステートメント」
「Public ステートメントの使用例」
を検索してみてください。


712:デフォルトの名無しさん
08/08/07 00:01:04
>>709
つりですか?

713:デフォルトの名無しさん
08/08/07 09:47:54
>>707
はい1×data_nです。

Dim data AS Variant

search=0
if 該当の行が見つかったら then
search=search+1


data(search) = range(cells(search,data_n),cells(search,data_n))

endif

複数行をまとめて配列に移したいのです。
unionでダメでした。
妥協するならせめて一行をまとめて移したい。
上記は妥協コードです。

714:y
08/08/07 17:31:25
>>713
やりたいことは、何となくわかりました。
・セルを上から一つ一つチェックして
・該当の行が見つかったら
・該当の行のデータを配列に書き込む
という流れですね。

2次元配列に含まれる、特定の一次元配列に対して、まとめて書き込みを
することはできません。
該当の行の値を一つ一つ書き込むことになります。

For i = 0 To data_n - 1
 data(search, i) = cells(該当の行 , i + 1)
Next

ちなみに、「該当の行が見つかったら」とありますが、
該当の行が全部で何行あるかは、あらかじめ分かるのですか。
それとも、見つかった数だけ配列のサイズを増減したいですか。


715:デフォルトの名無しさん
08/08/07 19:52:23
>>714
やりたいことはそうです。
data_nはあらかじめ与えられており、一定です。

配列に一行ずつ入れるのは無理なのですね。
では、見つかったセルを一気に写す方法はないでしょうか?
やはり
rng=union(rng,見つかった新たな行)
で最後に
配列にrngを代入したのですが、3行分しか入らなかったのです。

716:デフォルトの名無しさん
08/08/07 20:08:25
>>714
該当の行の数は決まってません。
1〜240個で変動します。


717:デフォルトの名無しさん
08/08/07 21:22:20
最近、yって子が頑張ってるね
まだまだVBAというかプログラム言語を始めたばかりのようだが
質問に答えるために調べる、質問に答える為に考えるというのは
結構身になるものだから、これからも頑張ろう

718:y
08/08/07 21:38:52
>>715
Unionで結合されたRangeは、内部的にはコレクション(のようなもの)であり、
二次元配列ではないので、直接に代入はできません。全体が連続していれば、
二次元配列と解釈してくれるので代入は可能なのですが、この場合は各範囲が
離れています。3行分入ったのは、Unionされた各範囲のうち、先頭の範囲から
3行分が偶然連続していたためと思われます。

さて、Unionされた範囲を取得ところまではなさっているようですので、
そこからどうもっていくかについてです。上記の通り、全体を直接代入できないため、
ここでもやはり、一つ一つ値を格納していくことになります。

まずは、格納先となる配列のサイズを確定します。dataは動的配列で宣言しておき、
 Dim data() As Variant
ReDimステートメントを使ってサイズを確定します。
 Redim data(1 To 行数, 1 To 列数)
列数は、data_n となります。さて行数はどうなるでしょうか?
ヒント:rng.Countで、Unionされた範囲rngに何個のセルが含まれるかを取得できます。

>続きます

719:y
08/08/07 21:40:46
>>715 (続き)

続いて、格納するためのループです。For Each で、
rngに含まれる各セルを1つずつtmpに取り出し、
data(r, c)に代入します。
ここでrは二次元配列の行番号、cは列番号です。

Dim r as Long, c as Integer, tmp as Variant
r = 1: c = 1
For Each tmp In rng
 data(r, c) = tmp
 c = c + 1
 If ??? > data_n Then
  r = r + 1 
  c = 1
 End If
Next

???には何を入れればいいか、考えてみてください。

720:y
08/08/07 22:24:41
>>717
情報系の教育は受けたことはないのですが、
最近、人にVBAを教えなければならない立場になってしまい、
ありとあらゆる質問が投げられてくるこのスレで
修行させていただいています。
自分のレスを見直すために、簡単な名前をつけています。

2年ほど前は、私も>>706>>401のような質問をしていました。
その頃アドバイスしてくださった方々には大変お世話になりました。

721:デフォルトの名無しさん
08/08/07 23:29:41
>>719
???はc。

ありがとうございます。
やはり一つづつですか。
しかし、それだとCell毎にExcelにアクセスするので速度が遅くなるような気がします。

できないことがわかったので、代案としては

Dim data as Variant (一次元配列用)
Dim r as Variant   (二次元配列用)
'-------一行丸ごと配列格納
data = range(cells(search,data_n),cells(search,data_n))

そのあとrからdataへ
つまり一次元配列から二次元配列へ一気に代入する方法はないでしょうか?



722:デフォルトの名無しさん
08/08/08 00:27:34
VBって、配列は弱いんでなかったっけ。
配列数指定しないといけないし。

723:デフォルトの名無しさん
08/08/08 00:39:34
1回の格納ごとにredim preserveしていってもそこまで遅くは無い。
というか、あきらめるべき。

ちなみにredim preserveを減らそうがためにVectorみたいな
一度にアロケートする成長リスト形式にしても速くならなかった。

724:デフォルトの名無しさん
08/08/08 00:46:27
>>723
いや、Cellsを毎回使うことが遅くなるということで。。。
tmpに一気に代入されているという解釈になるのかな。。。
【参考】VBA高速化
URLリンク(officetanaka.net)

725:デフォルトの名無しさん
08/08/08 00:49:48
あ、ごめん 上レスぜんぜんみてなかった

726:デフォルトの名無しさん
08/08/08 01:39:10
>>721
>しかし、それだとCell毎にExcelにアクセスするので速度が遅くなるような気がします。
おまえは馬鹿のクセに試しもせずに答えを求めるな
時間計って試してから出直して来い

727:デフォルトの名無しさん
08/08/08 02:00:11
セルがいくら多くてもシートやオートシェイプのオブジェクトをループする遅さに比べたら全然速い

728:デフォルトの名無しさん
08/08/08 03:35:17
セルを参照する数が多いと遅くなるよ。
だから範囲を全て配列に渡してから配列で演算するのが常套手段。


729:デフォルトの名無しさん
08/08/08 03:37:08
>>721>>716
>1〜240個で変動します。
つまりMAXで240×data_nのセル参照数となるから
data_nが50程度なら感じるほどに遅くなるよ。

730:デフォルトの名無しさん
08/08/08 05:46:25
>>721
速度を気にするなら >>728の言う通り一度範囲を全て配列に渡してから処理する方がいい
例えばこんな感じ

Sub hoge()
 Const date_N As Integer = 50
 Dim Buf As Variant, Buf2 As Variant
 Dim iC As Integer, iC2 As Integer, X As Integer
 
 With Worksheets("Sheet1")
  Buf = .Range(.Cells(1, 1), .Cells(250, date_N)).Value
 End With
 
 X = 1
 ReDim Buf2(1 To date_N, 1 To X)
 For iC = 1 To 250
  If Buf(iC, 1) = "A" Then
   ReDim Preserve Buf2(1 To date_N, 1 To X)
   For iC2 = 1 To date_N
    Buf2(iC2, X) = Buf(iC, iC2)
   Next iC2
   X = X + 1
  End If
 Next iC
 
 ReDim Buf(1 To UBound(Buf2, 2), 1 To UBound(Buf2, 1))
 For iC = 1 To UBound(Buf, 1)
  For iC2 = 1 To UBound(Buf, 2)
   Buf(iC, iC2) = Buf2(iC2, iC)
  Next iC2
 Next iC
End Sub

731:デフォルトの名無しさん
08/08/08 10:47:54
>>730
速度気にするなら無駄多すぎw

Sub hoge()
  Const DATA_N As Integer = 50
  Const DATA_ROW As Integer = 250
  Dim Buf As Variant
  Dim iC As Integer, iC2 As Integer, X As Integer

  Buf = Sheet1.Range("A1").Resize(DATA_ROW, DATA_N).Value

  For iC = 1 To DATA_ROW
    If Buf(iC, 1) = "A" Then
      X = X + 1
      For iC2 = 1 To DATA_N
        Buf(X, iC2) = Buf(iC, iC2)
      Next iC2
    End If
  Next iC

  Sheet1.Cells(DATA_ROW + 2, "A").Resize(X, DATA_N).Value = Buf
End Sub

732:デフォルトの名無しさん
08/08/08 13:32:19
時間計るのに、ミリ秒まで計る方法ってある?

733:デフォルトの名無しさん
08/08/08 19:07:14
API

734:デフォルトの名無しさん
08/08/08 20:55:33
240個だけw

735:y
08/08/08 21:05:51
速さへの関心が高いようですね。計測用のマクロを書いて、計ってみましたよ。
あくまで向学心(というか興味本位)です。速さが全てではないはずなので、
あまり過敏に反応しないでくださいね。

>>718-719
85 milliSec

>>730
20 milliSec

>>731(セルへの書き込みの部分は含まない)
10 milliSec

タイムは、10回計った平均です。
準備したテストデータは、
250行×50列の範囲に、1行おきに該当行(1列目の値が"A")を配置してあります。
つまり、該当行は150行です。
>>731は、配列変数のサイズが最後まで250行のままである点など、厳密な比較ではありません。
でも、セルへの書き込み時に切り捨てるという解決の仕方がおもしろいですね。勉強になります。

ちなみに、ミリ秒単位の時刻を得るために、
URLリンク(members3.jcom.home.ne.jp)
で公開されているモジュールを利用しています。

736:デフォルトの名無しさん
08/08/08 21:18:00
>>731
速度気にしてるつもりなのに無駄多すぎ

> Const DATA_N As Integer = 50
数値型、文字列型の定数で型指定するな

> Dim iC As Integer, iC2 As Integer, X As Integer
カウンタはIntegerで桁が足りてもLong使え

> Range("A1")
文字列での参照ではなくCells(1,1)とインデックス参照しろ

> Cells(DATA_ROW + 2, "A")
こちらも同じく "A" ではなく 1 で


っていうかこの話、配列クラス自作しちゃった方が早い気がする
無駄に注文多くて我が侭なのに、デフォで用意されてる配列でどうにかしようってのが間違いだろ

737:デフォルトの名無しさん
08/08/08 21:18:52
ExcelVBAでやる時点で間違っている

738:デフォルトの名無しさん
08/08/08 21:23:40
今のPCなら数百のシートを操作してもそんなにストレス感じないのに
msecオーダーで速度求めるならC++で書けよなと思った。

739:デフォルトの名無しさん
08/08/08 21:51:05
正直言って、VBAは速度気にしないで使えるのが気楽で良い。
VBAだしぃー。ってのが免罪符になる。

本当に商用プログラムを作るならばVBAでやる事が前提からして間違い。
マシンパワーに余裕が出てきた今だからこそ、速度は敢えて気にしない。

と言っても、cells選択したり、表示速度が極端に遅くなるのは論外ね。


740:デフォルトの名無しさん
08/08/08 21:51:07
ちなみにC++で書いたことあるけどそんなに劇的には速くならないけど

741:y
08/08/08 21:57:21
>>736
>文字列での参照ではなくCells(1,1)とインデックス参照しろ
おー、ほんのちょっと速くなった。
>カウンタはIntegerで桁が足りてもLong使え
Longにしてみたら、やはりちょっと遅くなるんですね。

>>737-738
すみません、つい出来心でやってしまいました。
「自分が提案したコードって、実はやたらと遅いの?」と思って確かめたかっただけです。
個人的には85milliSecで完了できれば充分じゃないかと思いますが...

>>739
ですよねー

>>721
ということでした。「一次元配列から二次元配列へ一気に代入する方法」ですが、やはり
「一気に」は無理です。そのかわり、いろんな別解やアドバイスが出てきて勉強になりましたね。
条件文は c で大正解です。これからも頑張ってください。

742:デフォルトの名無しさん
08/08/08 23:01:24
VBAでいろいろ書いて「これおっそいだろうなー」って思っても
たいがい人間の認識できる速さのプランク長ぐらいで終わってしまう。驚き

743:デフォルトの名無しさん
08/08/08 23:14:00
ただあれだ。
ページの表示設定を印刷モードだっけか。あれにしてVBA走らせるとむちゃ処理重いな。
screenupdate falseにすりゃ良いんだけど。

あと覚えてるのだと、cells.autofitがむちゃ重い。
その狂ったマクロ作った奴は、流石にクレーム食らってた。

744:デフォルトの名無しさん
08/08/08 23:22:45
FSOでネットワーク上のディレクトリ走査するのをExcel関数にして羅列してもなかなか遅くできる。

745:デフォルトの名無しさん
08/08/09 00:51:16
データの多いシートのAutoFitoはやばいぞ、VBAじゃなくても普通に遅い

746:デフォルトの名無しさん
08/08/09 09:43:06
質問です。 マクロでPCのシャットダウンはできるのでしょうか? 出来たら、やり方を教えてください
あと、MsgBoxをのバックを画像にすることは出来ますか?

Windows98
Office2000
マクロ初めてまだ間もないです

747:デフォルトの名無しさん
08/08/09 09:50:31
>>746
>Windows98
そんな過去の遺物を使うのはやめなさい。

>マクロでPCのシャットダウンはできるのでしょうか?
WinAPIを使えばできるはずですが。

>あと、MsgBoxをのバックを画像にすることは出来ますか?
日本語でOK。

748:デフォルトの名無しさん
08/08/09 10:58:21
>>746
API


749:746
08/08/09 13:43:59
>>747

メッセージボックスの背景を画像にしたいのですが、できますか?


よろしかったらマクロのやり方を教えてください。

750:デフォルトの名無しさん
08/08/09 14:37:09
>よろしかったらマクロのやり方を教えてください。
WinAPIを呼ぶだけです。それについては、>1の★4に該当するので教えられません。

>メッセージボックスの背景を画像にしたいのですが、できますか?
そんなことをするよりも、画像を貼ったユーザフォームを用意した方が早いと思います。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4635日前に更新/336 KB
担当:undef