Excel VBA質問スレ Part7
at TECH
[前50を表示]
550:デフォルトの名無しさん
08/07/22 06:38:45
>>544
Aだけど、>>519でやったのははtest(i as Integer)じゃなくて
test(i as Integer) as Integerだよ
ちなみにtest(i as Integer)をやってみたら5217
1違うな…
551:y
08/07/22 22:40:40
>>550
あ、すみません。Aをその通りやり直したら6453でした。
>>519と比べて1だけ違いますが、これでほぼ同じ結果になりましたね。
>>549
末尾再帰と呼ばれるスキームも、初めて聴きました。Wikipedia「末尾再帰」のコード例は、全然知らない言語なので
私には理解不能です。でも、スタックオーバーフローを「回避できる」と確かに書いてあるので、できたら知っておきたいです。
色々検索したら、べき乗を求める再帰関数を末尾再帰の形に書き換えたというC言語のコード例を見つけたので
真似をしてVBAに書き直してみたのですが...
URLリンク(itpro.nikkeibp.co.jp)
(このページの一番最後に紹介されています)
Function power_loop(m As Long, n As Long, a As Long) As Long
If n <= 0 Then
power_loop = a
Else
power_loop = power_loop(m, n - 1, a * m)
End If
End Function
Function power(x As Long, n As Long) As Long
power = power_loop(m, n, 1)
End Function
VBAではたぶんこういうコードになるはずですが、これって、やっていることはただの再帰ですよね?
>>549の説明どおりにはできていない気がします。
演算を*でなく+にしてLong値のオーバーフローを回避した上で6000回ぐらい再帰呼び出ししたら(引数n=6000)、
案の定スタックオーバーフローになってしまいました。
ちなみにVBで書かれた末尾再帰のコード例は検索してもなかなか見つかりません。
すみません、だんだんExcelVBA固有の質問ではなくなってきたので、他スレで同じ質問をするかもしれません。
552:デフォルトの名無しさん
08/07/22 23:29:56
>>551
てか、別に末尾再帰を経なくても全然いい。普通に再帰をループになおせさえすれば。
末尾再帰という形式になった再帰呼び出しのコードは、
ループの形に必ず書き直せるという性質が成り立つだけ。
一応、どういうものかだけ↓に書いておいた。
<<末尾再帰にする前>>
function factorial&(byval i%)
if i = 0 then
factorial = 1
else
factorial = i * factorial(i - 1) ' factorial(i - 1)の前に i * という『残りの操作』が残っているので末尾再帰ではない
end if
end function
<<末尾再帰にした後 (別にVBAでは末尾再帰にしても速くなるわけでも最適化されるわけでもない。Lispなら勝手に最適化される)>>
function factorial&(byval i%, optional result& = 1)
if i = 0 then
factorial = result
else
factorial = factorial(i - 1, i * result) ' 『残りの操作』が残っていないのでこれは末尾再帰
end if
end function
<<上記をループに書き直した後(VBAでもこういう形にすればスタックなぞ一定量しか要らん)>>
function factorial&(byval r%)
dim result&
dim i%
factorial = 1
for i = 1 to r
factorial = factorial * i
next i
end function
まあなんだ、末尾再帰とか勉強したかったらSchemeとかHaskellとか勉強すればいいんじゃね?
553:デフォルトの名無しさん
08/07/22 23:32:13
ごめん。最後の関数のresult&はいらん。
554:デフォルトの名無しさん
08/07/22 23:42:09
選択範囲をset して
For Eachでまわそうとすると
余分にまわりませんか?
Selection.Countでみるとときどきなんか多い…わらし?
555:デフォルトの名無しさん
08/07/22 23:43:36
コード晒せよ
556:デフォルトの名無しさん
08/07/23 04:35:09
>>552
君、うざいよ。
557:y
08/07/23 17:10:26
>>552
なるほど、納得です。>>549の説明も意味が分かりました。
・再帰のコードは、普通のループ構造で表現できる。
・再帰のコードをいったん末尾再帰の形に直しておけば、ループ構造に直すのが容易。
・末尾再帰のコードは、『残りの操作』(戻り値を使った演算)が必要ないため、理屈としては呼出元の変数の状態を保存しておく必要がない。
・言語によっては(あるいは賢いコンパイラは)この性質を利用して、末尾再帰のコードを、同一関数のくり返しの形(ループ構造)に最適化してくれる。
だから呼び出しのたびにスタックリソースの消費が増加することがない。
・でもVBAではそういう最適化はしてくれないから、最初から自分でループ構造に直して書く。
ありがとうございました。
>>554 >>555
558:デフォルトの名無しさん
08/07/23 17:15:16
VBAで、GUID(グローバル一意識別子)を取得したいのですが、
なにか関数などはありますか?
GetGUID的な、都度ユニークなIDを返してくれるような。
C++の方法はわかるのですが、VBAでやる方法がわかりません。
よろしくお願いいたします。
559:y
08/07/23 17:39:34
>>558
手元にあるリファレンスブックをざっと見ましたが、
そういう関数は私には見つけられませんでした。
その識別子を何に使いたいのか教えてくれたら、
他の方もアドバイスしやすいと思います。
560:デフォルトの名無しさん
08/07/23 20:16:36
>>557
だいたいその認識でOK。
誤解の無い様に言っておくが、(勘違いしていたらすまんこ)
全ての再帰がループに直せるわけじゃなくて、末尾再帰だけね。
561:デフォルトの名無しさん
08/07/23 20:34:49
>>558
VB GUID 生成
562:デフォルトの名無しさん
08/07/25 11:11:35
>>559 >>561
ありがとうございます。
できました。
URLリンク(support.microsoft.com)
563:デフォルトの名無しさん
08/07/26 04:38:05
文字列の置換に関しての質問です。
以下のような記述をしているのですが、
置換してほしくないものまで置換してしまいます。
たとえば文字列A12をB12に置換したいが、
文字列A123は置換せずそのままにしたいような場合、どうすればよいのでしょうか?
ちなみにWhat:=str1とReplacement:=str2は別シートの置換リストから引っ張ってきています。
ActiveSheet.Columns("A:A").Select
Selection.Replace What:=str1, Replacement:=str2
564:563
08/07/26 04:44:26
>>563の追記です。
1つのセル内には複数の文字列群があるため(A12とA123が同一セルにある)
xlWhole をつけてもだめでした。
565:デフォルトの名無しさん
08/07/26 06:20:22
A123を先にB123に変換
A12を変換
B123をA123に変換
では多分駄目なんだろなぁ
566:デフォルトの名無しさん
08/07/26 06:54:00
>>563
あくまでおいらのやり方ね。状況に応じて何種類か使い分けてるね。
・>>565さんのやり方。
str1の検索ワードにlenでの長さを出して、降順にソート。長い物から置換して行く。
・オートフィルタで完全一致させる物を抽出。んでマッチにしたセルを置換。
・上二つや、組み合わせで対応出来ない時はregexpのreplaceを使う。(regexpの話出ると荒れるんだよね・・・)
たぶん、検索文字列と置換文字列がデータテーブルに存在するならば、
オートフィルタか、長い順に置換で出来るような気がするよ。
567:デフォルトの名無しさん
08/07/26 06:57:31
>>564
>1つのセル内には複数の文字列群があるため(A12とA123が同一セルにある)
かぁ・・・・。
データテーブルを文字列の長い順にソートしてから、
オートフィルタの部分一致で抽出、見えてるセルにreplaceでどうかな。
568:563
08/07/26 07:57:01
>>565 >>566 >>567さん
朝早くからご回答ありがとうございます!
今日夜にでも長い順にソートで試してみたいと思います。
569:563
08/07/26 08:07:43
置換の>>563です、
あぁ・・・。
以下のような場合がマズイかもしれません。
もう少し調べたり考えたりしてみますね。
例)置換リスト A123→B123
対象データセルの文字列
A12 A123 A1234
※A1234までB1234になってしまう。
570:デフォルトの名無しさん
08/07/26 08:56:38
一旦配列に取り込んでVBAでReplaceした方がいいんじゃないのかな
571:デフォルトの名無しさん
08/07/26 09:00:50
あ、Replace関数使うんならLen関数も一緒に使うとかしないとダメだな
572:デフォルトの名無しさん
08/07/26 09:02:27
置換条件が結構厳しそうだね。
replaceだと一致は理論上の部分一致だし、
1セルに複数の文字列が入ってるとなると、オートフィルタも限界あるなぁ。
regexpのreplaceメソッドが良いような気がするけど、詳しい人の意見も聞きたいな。
セルの中で、どんな風に文字が配置されてるかが分からないけど・・・まぁ行けるかと。
A12A123A1234 のうちA123だけを置換したいなら、 "A123^A"で引っ掛けられるかな。
573:デフォルトの名無しさん
08/07/26 09:07:43
VBAのreplace使えるのって、A123もA1234も置換する場合に限られるような気がする。
もし、A123は置換するけど、A1234はそのまま、って場合にはちとまずい。
574:デフォルトの名無しさん
08/07/26 09:54:55
だから配列に取り込むんだよ
575:y
08/07/26 14:27:52
>>569
まず、>>563で
>文字列A12をB12に置換したいが、
>文字列A123は置換せずそのままにしたい
と書いていますが、2つの要求同士が矛盾しているので、
そのような動作はありえません。
解決の可能性としては、>>572の「セルの中でどんな風に文字が配置されているか」がポイントです。
つまり、文字の配置に規則性があるかどうか、ということです。
たとえば>>569で、対象データセルの文字列として「A12 A123 A1234」という例が示されていますが、
これを見る限り「文字列に含まれる各単語は、スペースで区切られている」という規則性が感じられます。
もし、すべての対象データセルの文字列がこの規則に従っているなら、望みの操作は可能です。
まずはすべての文字列に共通する規則性があるかどうかを確認し、
もし上記のような規則が存在するなら、>>570と>>574が薦めている
「配列にとりこむ」方法を検討してみてください。
この場合、Split関数が使えます。
576:デフォルトの名無しさん
08/07/26 15:19:23
>>569の例のように区切り文字がスペースって事なら(半角と全角が混在してるな・・・)
ActiveSheet.Columns("A:A").Select
For Each c In Selection
c.Value = RTrim(Replace(Replace(c.Value," "," ") & " ", str1 & " ", str2 & " "))
Next
とかでどうかな、遅いし全角スペースは半角になっちゃうけどね
577:デフォルトの名無しさん
08/07/26 21:04:21
何でもかんでもVBAの機能だけでやろうとすんなって。
使える物は何でも使おうぜ。
VBSだろうがAPIだろうがWHSだろうが、VBAから使える以上、VBAで良いと思うぞ。
578:デフォルトの名無しさん
08/07/26 21:27:32
Microsoft VBScript Regular Expressions
参照して、正規表現で置換かけるのはダメなん?
579:デフォルトの名無しさん
08/07/26 22:58:50
完全一致を望むならば、やはり正規表現だと思う。
580:y
08/07/26 23:48:07
>>576のレスを見て、全角と半角の混在に気づきました。
これではJoinは使えませんね...
私は正規表現は苦手で、普段はあまり使っていないのですが、
たしかにこの状況では正規表現が良さそうな気がしてきました。
半角・全角スペースどちらにもマッチしてくれる\bがかなり便利。
"\b(A12)\b" を探して "B12" にReplaceするだけで済みますね。
581:デフォルトの名無しさん
08/07/27 02:43:35
>>577
具体的にどうやるのか示せよ
582:デフォルトの名無しさん
08/07/27 08:18:41
どんな物を置換したいのか、どんな並びになってるのかが分かればマッチパターンを考える事は出来まっせ。
もし、住所録の置換なんかで、
○○県アルプス市〜〜 → ●●県foo市〜〜
××県南アルプス市〜〜 → △△県bar市〜〜
みたいなのだと、正規表現じゃないと無理ですな。
何にせよ、規則性を見つけ出してパターンを組む事から始めよう。
583:デフォルトの名無しさん
08/07/27 11:20:14
XP Excel2003で質問なのですが
480×640の画像のRGBの値を画素ごとに
R(480,640),G(480,640),B(480,640)
という配列に読み込みたいのですが可能でしょうか?
584:デフォルトの名無しさん
08/07/27 11:50:28
スレ違い
585:デフォルトの名無しさん
08/07/27 12:37:40
画素ごとに・・・ってあんた。
586:デフォルトの名無しさん
08/07/27 14:47:34
1000万画素の写真として、3000万個の配列ですか・・・。
考えただけで鬱・・・。
587:640*480がどうやったら1000万になるんだw
08/07/27 14:57:49
>>586
もし暗算が苦手でしたら、WindowsにしろLinux(Gnome)にしろ電卓アプリが付属していますので是非お使いください。
588:デフォルトの名無しさん
08/07/27 15:28:04
え・・・普通480×640って言ったら画像サイズの事じゃないの?
画素数は密度によって違うと思うんだけど。
589:デフォルトの名無しさん
08/07/27 15:46:09
>>588
画像サイズが pixel 単位表記ではない可能性の話?
仮に mm 表記で 100dpi とすると
640mm/25.4*100≒2520pixel
480mm/25.4*100≒1890pixel
2520x1890=470万画素
590:y
08/07/27 15:56:24
>>583
可能です。中級ぐらいのVBA解説書で時々見かける課題です。
まずは対象の画像ファイルをBinaryモードでOpenし、
配列変数にバイト単位で格納します。数行で済みます。
URLリンク(www.cocoaliz.com)
次に、その画像のファイル形式の仕様に沿って、画素データを抽出する
だけですが、画素ごとの色データを取得するのが目的であれば、
24bitモードのBMP形式の画像ファイルがもっとも簡単です。
他の形式の画像ファイルでも、いったん24bitのBMP形式に保存しなおして
から処理するといいでしょう。
BMP形式の仕様はこうなっています。
URLリンク(www.kk.iij4u.or.jp)
データ部には、1画素につきRGBの順で各1バイト(計3バイト)の
色データが並んでいます。(注意が必要なのは、並びが最下行から最上行の
方向になっている点です)
上記2サイトを参考にチャレンジしてみてください。
591:デフォルトの名無しさん
08/07/27 15:58:56
エクセルっていろんな事出来るんだね・・・ほんとすごいです。
592:y
08/07/27 16:24:18
すみません。>>590は「VBA解説書」→「VB解説書」の間違いです。
さすがにExcelVBAの解説書で、画像ファイル処理の例は見たことはありません。
ある意味>>584ですが、ついつい答えてしまいました。
593:583
08/07/27 16:57:26
画像サイズと画素数を混用してしまったせいで変な誤解をさせてしまったみたいです
すみませんでした。
>>590
非常にわかりやく解説していただいてありがとうございます!
ずばりこれを知りたかったんです。
ありがとうございます。
594:デフォルトの名無しさん
08/07/27 23:06:38
結局、置換の質問した人はうまく出来たのかな。
595:デフォルトの名無しさん
08/07/28 01:39:56
今頃痴漢してつかまってるよ
596:デフォルトの名無しさん
08/07/28 07:04:35
( ´_ゝ`)
597:563
08/07/28 22:36:20
ご報告が遅くなりましてすいません。置換の人です。
みなさんの知恵をお借りして、
私のつたないプログラム能力でなんとか作ってみました。
結局、セルを1つずつ読み込んで、
セル内の文字列に対してregexp正規表現 \b(str)\b で置換
という形にしたところ、要求を満たすことができました。
みなさんありがとうございました!
598:デフォルトの名無しさん
08/07/28 22:53:14
おめでとう
599:デフォルトの名無しさん
08/07/29 11:57:03
入力された文字が漢字か平仮名かを判定することは可能でしょうか?
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
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
4635日前に更新/336 KB
担当:undef