10 :デフォルトの名無しさん:2011/02/23(水) 17:45:59.06
ttp://www.excellenceweb.net/vba/class/class_method.html
このページの下の方の例文(足し算を行い、合計と平均を返すクラスの運用 その2)で
SATOU、SUZUKI、TAKAHASHI等の変数が20個も200個もある場合
整理されて、後で改造もしやすくするにはどうすればいいですか
Dim humans As Variant
humans = Array(, "SATOU", "SUZUKI", "TAKAHASHI", ・・・・・・・・
とかしてループして各メソッドを呼ぶんですかね


11 :デフォルトの名無しさん:2011/02/23(水) 18:21:24.52
>>10
俺だったら配列で引き渡すわ
それが個人的には1番楽だし改修も引数だけでいいしね
あと、Variantは関係ない


12 :デフォルトの名無しさん:2011/02/23(水) 20:53:31.46
WinXP sp3 Excel 2003
1024列×768行の数値が書かれたCSVファイルをラインモードで読み込み、平均した後、
256列768行にして数値を入力するような命令を実行しています。
この数値の中で、ある値以下の平均を取っていき、その変動が最小になる値を求めたいです。
(10以下平均-9以下平均)、(11以下平均-10以下平均),,,,(30以下平均-29以下平均)
Averageifがないので、SUMIF()/COUNTIF()のように計算させ、Do loop等で
順番に計算させようとしたところフリーズしてまともに計算できません。
そこであらかじめシートの方に、A列にSUMIF/COUNTIFを入力し、
B列にA3-A2のように入力し、B列が最小になる行のA列の値を取得しようと思います。
どのようにしたらよいでしょうか。またほかに何かよい方法はないでしょうか。


13 :デフォルトの名無しさん:2011/02/23(水) 21:18:54.63
>12
パフォーマンスを求めるならExcel/VBAじゃなくて.NETなり
数学計算できるソフトほうがいいんじゃないかな?
あと、どうしたらいい?じゃなくて思ったことをじゃなくてVBAやってみたら?
ロジックを考えてくれっていうのはナシの方向で。


14 :デフォルトの名無しさん:2011/02/23(水) 21:19:10.66
>>12
if文で最小値比較して、それをfor文で回すだけじゃね?


15 :デフォルトの名無しさん:2011/02/23(水) 22:21:03.12
>>13 >>14
あまり美しいとはいえないですが、
A列にSUMIF/COUNTIF
B列にA3-A2,,,,
適当なセルにSUMPRODUCT((B10:B30=MIN(B10:B30))*ROW(B10:B30))で行番号取得、
Cells()でA列のこの行番号の値を入れて取得でできました。
SUMIF/COUNTIFもマクロ上だと重いですが、セル上だとさくっといくみたいです。


16 :デフォルトの名無しさん:2011/02/24(木) 00:38:00.27
>>12
たかだか70万件のデータでフリーズするとは、あきらかにプログラムがタコだな
アルゴリズムをよく考え直した方がいい
まあ、とりあえずExcel2010買ってこい
小細工しなくても1024列のデータがそのまま読み込めるから
プログラムが少し楽になる


17 :デフォルトの名無しさん:2011/02/24(木) 01:11:43.68
>>16
ど素人ゆえプログラムもかなりのへたれですが、
パソコンもへたれです。pen4世代のCeleron1.8Gのノート。
会社パソコンなもので、ハード、ソフトともにアップデート不可です。


18 :デフォルトの名無しさん:2011/02/24(木) 04:04:46.60
>>12
何をやりたいのか、よく判らないが
『フリーズしてまともに計算できない』コードにはバグがある可能性が
高い気がする
昔、同じくらいのマシンで数十分かかる処理をさせた事もあるが
この場合、無限ループに陥っている可能性を疑う
それと毎回セルに書いていたりする?
その場合、
Application.ScreenUpdating = False
とかは使っている?


19 :デフォルトの名無しさん:2011/02/24(木) 05:53:39.00
フリーズ=単に時間のかかる処理の実行中でエクセルが反応しない の意味なんじゃね?


20 :デフォルトの名無しさん:2011/02/24(木) 06:31:38.57
>>12
たぶん、プログラムをちゃんと作ればそんなに時間はかからないと思うんだけど、
その説明だけでは不明な部分がいくつかあるから具体的なプログラムが示せないんだよなあ
まず「ラインモード」ってなんだ?
たぶん、文章で説明するのはかなり難しいだろうから、現物を見た方が早い
そのデータとExcelのファイルは公開できる?


21 :デフォルトの名無しさん:2011/02/24(木) 07:54:34.68
>>18
使うのが基本。


22 :デフォルトの名無しさん:2011/02/24(木) 07:57:01.13
あとメモリはいっぱい積もうな。8Gなんて今余裕だろ。
これで100万件ぐらいでフリーズしない。


23 :デフォルトの名無しさん:2011/02/24(木) 08:01:40.30
>>22
>>17の状況じゃ無理だろう
まあ、このスペックでもこのデータ量なら動くと思うけどね


24 :デフォルトの名無しさん:2011/02/24(木) 13:18:30.49
頭の弱いやつがいくら高性能パソコンでメモリいっぱい積んでも根本的な解決にはならん。
他言語でも同じ。
まず計算ロジックの見直しだな。
SUMIF()/COUNTIF()なんてのは論外だよ。
>>16の言うとおり。


25 :デフォルトの名無しさん:2011/02/24(木) 13:28:12.58
(10以下平均-9以下平均)、(11以下平均-10以下平均),,,,(30以下平均-29以下平均)をSUMIF/COUNTIFかよ。
ソートすりゃどうにでもなりそうだな。


26 :デフォルトの名無しさん:2011/02/24(木) 14:46:15.77
ピボットテーブルでグループ化して平均出せばいいんじゃないの?


32 :デフォルトの名無しさん:2011/02/24(木) 20:37:23.79
B7からK19までを一行おきに色を付けたいと思い下の通りに
作ったのですがうまくいきません;;どこが間違っているか教
えて下さい。宜しくお願いします。
Sub test()
For CellGyo = 7 To 19 Step 1
Range("B" & CellGyo & ":" & "K" & CellGyo).Select
Selection.Interior.ColorIndex = 34
Next CellGyo
End Sub


33 :デフォルトの名無しさん:2011/02/24(木) 20:54:42.82
step 1 じゃなくて step 2
step 1ってことは、色を塗って、次はその下の行を塗る
1行ずつってことは、色をぬった行の2行下の行を塗るわけだ


34 :デフォルトの名無しさん:2011/02/25(金) 12:12:12.41
>>33
ありがとうございます!理由まで書いて頂いて本当に助かりました!!


35 :デフォルトの名無しさん:2011/02/25(金) 12:17:28.14
>>32
Sub a()
  With Range("B7:K19")
    .FormatConditions.Add Type:=xlExpression, Formula1:="=MOD(ROW(),2)=1"
    .FormatConditions(1).Interior.ColorIndex = 34
  End With
End Sub


36 :デフォルトの名無しさん:2011/02/25(金) 15:18:34.17
良スレ


37 :デフォルトの名無しさん:2011/02/25(金) 19:54:03.97
>>32
Sub b()
Dim R As Range
For Each R In Range("B7:K19")
If R.Row Mod 2 Then R.Interior.ColorIndex = 34
Next
End Sub


38 :デフォルトの名無しさん:2011/02/26(土) 00:27:10.81
みなさん昨日はありがとうございました。VBAを始めてまだ数日なので、教えて頂けてとても助かります!
今日は4月度売り上げデータのシートの値を月別売り上げ報告書のシートに転記したくて次の様に作った
のですがエラーになってしまいました;;どうしたらエラーにならないか教えてください。本を読みなが
らやりましたが分からないのでどうか宜しくお願いします。
Sub 報告書作成()
Dim CellGyo As Long
Dim HoukokuGyo As Long
Dim Tanto As String
Dim Tokuisaki As String
Dim Tiku As String
Dim Gyoshu As String
Dim Month As String
Dim Uriage As Currency
For CellGyo = 3 To 65536
Sheets("4月度売上げデータ").Select


39 :デフォルトの名無しさん:2011/02/26(土) 00:28:53.04
続き①です
Range("C" & CellGyo).Select
Tanto = Selection.Value
Range("D" & CellGyo).Select
Tokuisaki = Selection.Value
Range("E" & CellGyo).Select
Tiku = Selection.Value
Range("F" & CellGyo).Select
Gyoshu = Selection.Value
Range("H" & CellGyo).Select
Uriage = Selection.Value
If Tanto = "" Then
Exit For
MsgBox "処理が終了しました"
End If
Next CellGyo


40 :デフォルトの名無しさん:2011/02/26(土) 00:29:43.70
続き②です
Sheets("月別売り上げ報告書").Select
For HoukokuGyo = 7 To 65540
Range("C" & HoukokuGyo).Select
Selection.Value = Tokuisaki
Range("D" & HoukokuGyo).Select
Selection.Value = Tiku
Range("E" & HoukokuGyo).Select
Selection.Value = Gyoushu
Range("F" & HoukokuGyo).Select
Selection.Value = Uriage
Next HoukokuGyo
End
End Sub


41 :デフォルトの名無しさん:2011/02/26(土) 01:28:16.83
>>38
デバッグのやり方は経験を必要とするが、コードを書いたら
まず、メニューの『デバッグ』から『VBAProjectのコンパイル』を選ぶ
これにより、あなたのコードで、すぐ判るのは
Dim Gyoshu As String
で定義しているが
Selection.Value = Gyoushu
と書いているところがあり、これの定義がされていない
(つまり変数名が間違い)
なお、『ツール』メニューの『オプション』を選び、『編集』タグで
『変数の宣言を強制する』にチェックをつける事が前提


42 :デフォルトの名無しさん:2011/02/26(土) 01:32:56.49
>>38
エラーが出たなら最低限どんなエラーが出たかぐらい書け。あとExcelのバージョンも書け
エラーの原因をエスパーすると、
4月度売上げデータのH列に数字以外が入ってる行がある
Excelのバージョンが古くて月別売り上げ報告書に65540行もデータを作れない
のどっちか。でもたぶんエラーでなくても思った通りには動いてないと思うけどw
Sub 報告書作成()
    Dim CellGyo As Long
    For CellGyo = 3 To 65536
        If Sheets("4月度売上げデータ").Cells(3, CellGyo).Value = "" Then
            Exit For
        End If
        Sheets("月別売り上げ報告書").Cells(CellGyo + 4, 3).Value = Sheets("4月度売上げデータ").Cells(CellGyo, 4).Value
        Sheets("月別売り上げ報告書").Cells(CellGyo + 4, 4).Value = Sheets("4月度売上げデータ").Cells(CellGyo, 5).Value
        Sheets("月別売り上げ報告書").Cells(CellGyo + 4, 5).Value = Sheets("4月度売上げデータ").Cells(CellGyo, 6).Value
        Sheets("月別売り上げ報告書").Cells(CellGyo + 4, 6).Value = Sheets("4月度売上げデータ").Cells(CellGyo, 8).Value
    Next CellGyo
    MsgBox "処理が終了しました"
End Sub
やりたいのはこういうことじゃないのか


43 :42:2011/02/26(土) 01:43:43.61
>>41
うは、普通に見落としてたわ
ちなみに、『変数の宣言を強制する』は後からチェック入れてもダメだからな
あれは最初からコードの頭にOption Explicit入れてといてくれるだけだから
俺の感では今回はおそらくそのエラーではないと思うが


44 :41:2011/02/26(土) 07:33:55.33
>>43
実は、同感
何度か回答してきたけど、デバッグの基本的なやり方とか
書いておかないと、きりがない気がしてきたのでw
コンパイルとブレークポイントを覚えるだけで質問以前に
解決する事例も少なくないように思う


45 :デフォルトの名無しさん:2011/02/26(土) 10:00:57.92
終了判定をループ外に出して
シート名のハードコードも個人的に気持ち悪いので定数にしました。
Sub 報告書作成()
Dim CellGyo As Long
Dim GyoEnd As Long
Const Read_Sh As String = "4月度売上げデータ"
Const Write_Sh As String = "月別売り上げ報告書"
GyoEnd = Sheets(Read_Sh).Cells(3,3).End(XlDown).Row
If GyoEnd > 65532 then
GyoEnd =65532
End If
For CellGyo = 3 to GyoEnd
Sheets(Write_Sh).cells(CellGyo + 4, 3).Value = Sheets(Read_Sh).cells(CellGyo, 4).Value
Sheets(Write_Sh).cells(CellGyo + 4, 4).Value = Sheets(Read_Sh).cells(CellGyo, 5).Value
Sheets(Write_Sh).cells(CellGyo + 4, 5).Value = Sheets(Read_Sh).cells(CellGyo, 6).Value
Sheets(Write_Sh).cells(CellGyo + 4, 6).Value = Sheets(Read_Sh).cells(CellGyo, 8).Value
Next CellGyo
MsgBox "処理が終了しました"
End Sub
ただ、質問主さんが説明不足なので分かりませんが、
もしかしてこのシート、別々のブックだったりしませんかね?
同じブックの中でこんな転記したってあまり意味が無い作業のような・・・
本来は、全体の売り上げデータが入ったブックから担当ごとのブックに転記、
という作業なんじゃないかなぁという気がします。
(それにしては担当者の選択処理が無いけど)


46 :デフォルトの名無しさん:2011/02/26(土) 12:32:13.66
個人的な好みで言えば、同じオブジェクトを何度も参照する時はWith、
複数ある時は変数にまとめたいところ
Set WS = Sheets(Write_Sh).Cells(CellGyo + 4, 3)
Set RS = Sheets(Read_Sh).Cells(CellGyo, 4)
WS.Offset(0, 0).Value = RS.Offset(0, 0).Value
WS.Offset(1, 0).Value = RS.Offset(1, 0).Value
以下略
わざわざOffsetを並べてるのは、セル番号が不自然に飛んでるから、
あとで参照先を増やしたり減らしたり改造が必要になる可能性がありそうだから
修正箇所をわかりやすくするのが目的


47 :38:2011/02/26(土) 12:55:34.54
何のエラーか書いていなくてすみません。次からはちゃんと分かって頂ける
ように書きます。エクセルは2007です。そして2つのシートは同じブックの
ものです。
これは実際仕事で使うものではなく通信教育の課題です。もっと勉強して
から課題に取り組めば良いのですが提出期限明後日なので・・・。
みなさんありがとうございました!!


54 :デフォルトの名無しさん:2011/02/27(日) 12:38:40.55
Private Sub Main()
 Dim c As Variant,i As Long
 c=ThisWorkbook.Worksheets("Sheet1").Range("A1:V17616")
 For i = 0 To 999999999999999
  calc c
 Next i
End Sub
Main内で全く変更されない変数cがあって、その変数cがcalc関数にパラメータとして渡される場合
変数cはモジュールレベル変数とした方が良いか、ローカル変数とした方が良いかアドバイス下さい


55 :デフォルトの名無しさん:2011/02/27(日) 12:40:19.82
訂正
全く変更されない
    ↓
c=ThisWorkbook.Worksheets("Sheet1").Range("A1:V17616")以降全く変更されない


56 :デフォルトの名無しさん:2011/02/27(日) 12:41:53.94
Step 1 も忘れてた


57 :デフォルトの名無しさん:2011/02/27(日) 12:48:31.23
>>54
変数等のスコープは可能な限り狭いほうがいい。


58 :デフォルトの名無しさん:2011/02/27(日) 12:56:40.38
>>57
パラメータとして渡した方が良いんですか
ありがとうございました


59 :デフォルトの名無しさん:2011/02/27(日) 13:03:14.09
>>57
それ、何故か?ということについて、
詳しく開設されている本とかサイト知りません?


60 :デフォルトの名無しさん:2011/02/27(日) 13:13:43.94
その変数がどこで使われているのかとか判り辛くなるから。
一ヵ月後に修正とかしようとすると簡単に死ねる。
>>54 の例だと、cに設定した内容が他で参照される可能性とか
考えなくてはならなくなる。
ローカル変数なら、そもそもあり得ないから頭を使わなくて済む。


61 :デフォルトの名無しさん:2011/02/27(日) 13:18:38.19
>>59
>>57じゃないけど
友人がシステム保守の仕事をやっているわけだが
パブリック変数を安易に使うな!と怒っていたなw
パラメータで渡しておけばデバッグは相当楽になる
(大抵はその関数だけ見ておけばよい)
自分は一人で組んでいる場合は、パブリックに逃げる癖があるけどw


62 :デフォルトの名無しさん:2011/02/27(日) 14:52:46.52
>>59
個人的には、
メソッドを後でコピペで再利用しようと思っても出来ない。
変数の状態が追跡しにくい。
その中でもフラグ系は特にひどいな。


63 :デフォルトの名無しさん:2011/02/27(日) 15:44:55.87
>>61>>62
なるほど。ありがとうございました。
今、高速化する方向で書いている最中なので気になりました。


64 :デフォルトの名無しさん:2011/02/27(日) 16:20:28.94
>>63
可読性や安全性、バグの出にくさと処理速度は反比例するからねー
コア部分をうまくモジュール分けしてブラックボックス化するぐらいしか対応策はないと思う


65 :デフォルトの名無しさん:2011/02/27(日) 16:28:14.74
引数渡しをパブリック変数化することで高速化?
まずは本当にそこがネックになっているか確認したほうがいいと思うよ。


66 :デフォルトの名無しさん:2011/02/27(日) 16:32:31.54
>>65
違う。ループ内とかのブロック変数の話。


67 :デフォルトの名無しさん:2011/02/27(日) 16:40:19.75
VBA でブロック変数って With しか思いつかないんだけど、
どこからそんな話が出てくるんだ?
そもそも >>58 で、「パラメータとして渡した方が良いん
ですか」と言ってるし。


68 :デフォルトの名無しさん:2011/02/27(日) 16:47:40.93
>>67
すみません。>>57から乗りました。
ブロック変数じゃなくてブロック内定義変数について
気になってました。


69 :デフォルトの名無しさん:2011/02/27(日) 17:33:48.88
だから、そもそも VBA に With 以外のブロックなんてないだろ。
これ以上何か聞きたいなら、>>52 のようにソースとともに書き
込んだほうがいいよ。


70 :デフォルトの名無しさん:2011/02/28(月) 09:46:25.98
>>54だったら定数化もありだね。
const付けられないから変数になっちゃうけど。


84 :デフォルトの名無しさん:2011/03/02(水) 13:38:32.17
置換について分からないことがあるので教えてください。
セルA1に文字と数字が入った
ABC123DEFというような文字列があります。
この中の数字のみ(文字も数字も桁数は一定ではありません)
置換したいのですが、例えば0から200の間であれば置換
というようにReplaceを使った場合指定する方法はあるのでしょうか?
お願いいたします。


85 :デフォルトの名無しさん:2011/03/02(水) 14:12:05.65
>>84
ない
数字と文字を分けて数字の大きさを判断して置き換える、というプログラムを自分で作る必要がある


88 :デフォルトの名無しさん:2011/03/02(水) 21:26:05.84
>>84
正規表現で数字を取得してCintした数値を条件分岐すれば良い


86 :デフォルトの名無しさん:2011/03/02(水) 18:43:35.02
流れぶった切ってすみませんが、どなたか教えてください。
Win7 64bit、Excel2007、CPU Corei7 980X、メモリ12GB の環境です
まず一地点分のファイル(新規ワークブック)を作成して、
次に
一日分のデータ(一つ30MBぐらいのcsvファイル)を開いて、
その中の一列(約43万行)を新規ブックにコピー
クローズして次のcsvファイルを同様に処理、
一か月分で新規ブックを保存、
新たな新規ブックを作成
というのを30回ほど繰り返すマクロがあるのですが、
(つまり30地点、30日で計900回オープン、クローズを繰り返す)
このマクロが処理の途中でよく止まりました。
(エクセルは起動しているがマクロは終了している
エラーメッセージも特に無し)
タスクマネージャで見てもCPU使用率もメモリ使用量も20%弱なので
PCスペックの問題ではなさそうなのですが、
エクセル上のリソース不足を疑いました。
そこでWebで調べたら
DoEventsという命令を実行させれば良いらしいと分かったので、
実際に試したら確かに止まらなくなりました。
ただ、なぜ効果があるのかが分からないのでちょっとモヤモヤしてます。
どなたか、DoEventsにどのような効果があるのか教えてください。


87 :デフォルトの名無しさん:2011/03/02(水) 18:59:19.45
VBAからタスクが帰ってこないことを無限ループとみなしてExcelが強制的にストップさせてたのを
DoEventsで定期的にExcelにタスクを回すことで処理が継続できるようになったとか
勘ですまん


89 :86:2011/03/02(水) 22:16:20.31
>>87さん
どうもありがとうございます。
無限ループですか。
確かにForNextで地点ごとのループと、一月分のループをネストして
その中でひたすらオープン・コピー・クローズを繰り返してましたから
無限ループに近かったかもです。
処理を完走させるには10時間以上回しっぱなしで、
その間エクセルでは他の作業が一切出来ませんでした。
私はファイルオープンしたときに確保したメモリを
ファイルクローズ時にきちんと解放できていないのではないかと疑っていましたが、
理由はなんにせよ、
エクセルには止まるなら止まるで何らかのアナウンスをしてほしいところですね。
マクロ停止の理由はともかく、
それを何らのエラーメッセージも出さずにただ止まるだけというのは
アプリケーションの挙動としてどうかと思いますね。


92 :デフォルトの名無しさん:2011/03/03(木) 00:08:10.26
>>89
何となくですが、
Application.ScreenUpdating = False
が記述されていない気がします。
何回もオープン・コピー・クローズしたため、
描画の方に問題が生じた可能性は無いでしょうか?


93 :デフォルトの名無しさん:2011/03/03(木) 00:09:29.80
>>89
>マクロ停止の理由はともかく、
>それを何らのエラーメッセージも出さずにただ止まるだけというのは
>アプリケーションの挙動としてどうかと思いますね。
いや理由は大事なんだが
VBAのエラーなのに何のメッセージもなく停止するのは確かにどうかと思う
が、あまりそういう状況は見たことがない
VABが無限ループしたからと言って、勝手に停止する機能も聞いたことがない
(スタック不足等のエラーで止まることはあるけど)
それらがDoEventsで解消される理由もわからない
あれは制御をいったんOSに戻すだけのものだが
(まあ、DoEventsについては不思議な副作用を起こすことはまれによくあるが)
実際にはエラーでとまってるのに、エラーハンドリングが適切じゃないので
だまって停止したように見えるだけじゃないかと思うんだが、差し支えなければ
実際のコードを晒してみてはくれないか


94 :デフォルトの名無しさん:2011/03/03(木) 00:17:18.88
>>89
Application.Calculation = xlManual
も入れた方がいいな
今どきの64bitマシンで、ファイルをたった900個開く程度で落ちるなんて考えられん
計算してみると1ファイルあたり40秒もかかってることになるわけで
全体で10時間というのも、ちょっと遅すぎる気がする
いっぺんコード晒してみ?


96 :デフォルトの名無しさん:2011/03/03(木) 00:45:42.87
VBAだし43万行だし、40秒はあり得ない話ではなさそう
ところでOffice 2007って32bitアプリじゃないの?
32bitプロセスってメモリ空間2GBしか使えないんじゃなかったかな。12GBの20%弱ってそれに合ってるよね。
メモリの問題ではないかもしれんが、もしかしたらDoEventsでガベージコレクトできるようになって、メモリが解放されたから動く、とか。


97 :86:2011/03/03(木) 00:47:46.46
>>92-93
どうもすみません、コードを出したくても会社のPCにしか入ってなくて
しかもデータの持ち出し禁止なのでちょっと提示できません。
一応、守秘義務契約もあるのでデータの詳細も明かせないのですが、
頭で覚えてる範囲で書きますと以下のような流れです。
Application.ScreenUpdating = False
Application.Calculation = xlManual
でシートの再計算と画面更新を停止
For i= 1 to 30 '地点ごとループ
転記用の新規ブック作成
For j=1 to 30 ’日を表すループ(実際の日数は31とか28とかの事もあります)
i地点、j日 のCSVファイルをひらく
新規ブックの J列にCSVのデータをコピー
CSVクローズ
Next j
i j を基にした名前で新規ブックを保存
Next i
シートの再計算と画面更新を再開
大体こんな感じです。
扱うデータの大きさはちょっと大きめですがマクロとしては至極単純なものだと思います。
エラー処理は入れてませんが、起こりうる可能性のあるエラーとしては
読み込み元のCSVファイルが存在しないとか、
保存するブックと同名のファイルがすでに存在する、などがありますので、
そういったエラーは起きないようにマクロ実行前にファイルの確認はしています。
(というかそういうミスではエラーメッセージがちゃんと出ます。)
・・・ちょっと自分でも分かりにくい説明なので、
明日にでもコードをきちんと確認して再度書き込みさせていただきます。


98 :86:2011/03/03(木) 00:52:25.74
>>95-96
すみません、>>93を読んでからリロードせずに書いてたので
気づきませんでした。
アドバイスどうもありがとうございます。


99 :86:2011/03/03(木) 00:54:40.63
うわぁぁぁぁテンパッてて安価ミスった。
>>95-96ではなく
>>94さん、>>96さんでした。
ほんとすみません


100 :デフォルトの名無しさん:2011/03/03(木) 00:56:32.61
あとCorei7 980Xは12スレッドだから、Excelが計算に2スレッドをフルに使えば20%弱だな
たしか設定で使うスレッド数を決められた様な気がするから、増やせばもっと早くなるかもね


101 :デフォルトの名無しさん:2011/03/03(木) 02:03:48.35
行数だけでなく列数も書いてもらえると、再現実験がやりやすくなるんだけどなあ


102 :デフォルトの名無しさん:2011/03/03(木) 06:58:58.41
>>97
保証はできないけれど
For j=1 to 30 ’日を表すループ(実際の日数は31とか28とかの事もあります)
i地点、j日 のCSVファイルをひらく
新規ブックの J列にCSVのデータをコピー
CSVクローズ
Next j
の、CSVクローズの直後か直前に、新規ブックを保存 した方が良い気がする
昔、ワードのVBAで新規ファイルを大量にいじる処理をした時、
同様のエラーが出て、随時保存で解決した
ワードとエクセルは違うかもだけ、大量の変更履歴を内部的に
保持できなくなったのが原因の模様だった


103 :デフォルトの名無しさん:2011/03/03(木) 07:12:56.83
>>97
それと
『エラー処理は入れてませんが』
とあるけど、転ばぬ先の杖で入れた方が良いと思う
ホント、世の中、びっくりするようなことが起きるもんだってw


104 :デフォルトの名無しさん:2011/03/03(木) 07:29:56.33
>>97
五月雨式で、申し訳ないがもう一つ
それだけ長い処理だと、自動バックアップが影響しているのかも?
(結果的に>>102、あるいは自動バックアップをオフにするべきか?)


105 :86:2011/03/03(木) 07:38:10.09
>>100-104
おおっ!
みなさん有難うございます。
出勤前でばたばたしてますのでひとまずお礼のみで失礼します。
良かったらまた今晩よろしくお願いします。


116 :86:2011/03/04(金) 01:20:52.85
86です。昨日の続きをよろしくお願いします。
必要ない部分は省きましたが大体こんなコードです。
モジュールの頭に
Option Explicit
Option Base 1
が書いてありまして、
Application.ScreenUpdating = False
Application.Calculation = xlManual
も実行済みです。
また、下記変数は親プロシージャから引数として渡してます。
Dim Mnth As Long '月
Dim Yr As Long '年


117 :86:2011/03/04(金) 01:22:26.42
Private Sub ファイル集計(ByVal Yr As Long, ByVal Mnth As Long)
Const POINT_COUNT = 30 '地点数
Dim MyLdPth As String '読込元のパス
Dim MySvPth As String '保存先のパス
Dim MyFldr As Variant '地点名
Dim MyNwBk as Workbook '新規ブック
Dim i As Long
Dim j As Long
MyLdPth = "C:\****\****\"
MySvPth = "C:\****\****\"
MyFldr = Array(***,***,***,***,……) '各地点の名称セット
For i = 1 to POINT_COUNT
Set MyNwBk = Workbooks.Add(xlWBATWorksheet)
'本来はここに1列目に時刻、1行目に日付を入れる処理が入ってます。
'約43万行とは0.2秒刻みで24時間 = 43,2000行です。
For j = 1 to MnthCnt(Yr, Mnth) '月の日数はFunctionで処理してます
Workbooks.Open(MyLdPth & MyFldr(i) & "\" & Format(i,"00") & "_" & Yr &
Format(Mnth,"00") & Format(j,"00") & ".csv")
With ActiveWorkbook.Sheets(1)
.Columns(4).EntireColumn Copy Destination:= MyNwBk.Sheets(1).Cells(2,j+1)
End With
ActiveWorkbook.Close
'**** ここにDoEvents を入れたら止まらなくなりました。 ****
DoEvents
Next j
MyNwBk.Close SaveChanges:=True, FileName:= MySvPth & "\" & MyFldr(i) &
_ & Yr & Format(Mnth,"00") & ".xlsx"
Set MyNwBk = Nothing
Next i
End Sub


118 :86:2011/03/04(金) 01:23:18.98
'月の日数を求める関数
Private Function MnthCnt(ByVal Yr As Long,ByVal Mnth As Long) As Long
Select Case Mnth
Case 1, 3, 5, 7, 8, 10, 12
MnthCnt = 31
Case 4, 6, 9, 11
MnthCnt = 30
Case 2
MnthCnt = CDate(Yr & "/03/01") - CDate(Yr & "/02/01")
End Select
End Function
現時点で(DoEventsがあれば)問題なく動作してますので
ループ中でのブック保存などは入れてません。
現状でもファイルのオープンとクローズ(セーブ含む)に一番処理時間がかかって
いるので、ループ中に保存処理を入れると処理速度が極端に遅くなりそうです。
エラー処理については、
何をチェックすべきかも良く分かっていません。
先にも書いたとおり
ループ中でオープンするファイルは確実に存在しているので、
他にチェックすべきものが思いあたらないです。


119 :86:2011/03/04(金) 01:36:28.13
>>117 におかしなところがありました
正しくはこうです
With ActiveWorkbook
.Sheets(1).Columns(4).EntireColumn Copy Destination:= MyNwBk.Sheets(1).Cells(2,j+1)
.Close
End With


120 :デフォルトの名無しさん:2011/03/04(金) 03:18:05.71
>>117
Workbooks.Addでは追加したブックがアクティブになるとの記載があるが
Workbooks.Openにはその保障はなさそうだ(EXCEL2007のヘルプによる)
なので With ActiveWorkbook.Sheets(1)のなか辺りでエラーが出てる可能性はある
その位置でDoEventsいれて正常に動作するなら、連続でオープンクローズすると
思ったブックがアクティブになってないのが改善してるのかもしれん
OS側の処理が追いついてなかったのがDoEventsで改善されてる可能性が無いわけでもないが
いちど
Workbook.open ...
With ActiveWorkbook...

With Workbook.open ...
にして、DoEventsなしで動くかみてみたら?
ちなみに、行全部コピーして、行全部じゃないRangeに張りつけって、正常に動くのか?


121 :デフォルトの名無しさん:2011/03/04(金) 03:49:34.09
>>120
セルのコピペの動作は手動でやるのと同じだよ
選択範囲のサイズが違った場合は一部が切り取られたり、同じ物の繰り返しになったりする
全データコピーなら、あまりいい方法じゃないね


122 :86:2011/03/04(金) 03:58:15.55
>>120
ありがとうございます。
実は明日から3日間休みなので、次にPCさわれるのが月曜日でして月曜日に確認したいと思います。
>ちなみに、行全部コピーして、行全部じゃないRangeに張りつけって、正常に動くのか?
すみません、
これに関しては実はこの辺うろ覚えで書いたんで間違いかもしれないです。
会社のPCではUSBメモリその他のメディアが使用禁止なので、
VBE開いて該当部分を手書きでメモにしまして、
さらに家のPCにはエクセルが入ってないので
手書きのメモを元にメモ帳で書いたのをレスとして貼り付けました。
ですので若干おかしなこと書いてる可能性があります。
改めて確認しなおして月曜日以降に報告させていただきます。
勝手ながら今日はこれにて失礼します。


124 :デフォルトの名無しさん:2011/03/04(金) 12:07:45.23
>>118
DoEventsを入れて動くのであれば、完成としてもよいかもしれない
そもそも、最初の質問が『DoEventsにどのような効果があるのか』なので
それについて考えてみた
DoEventsは、制御を一時的にOSに渡すための命令で使う例としては
数時間かかるような処理を、ボタンのクリックで中止させるような場合に
使われる
この場合、メイン処理のLoop中で、ある変数がTrueならば処理を抜ける、
さらにボタンを押すとその変数にTrueをセットするという書き方ができるが
DoEventsを使わないと、『ボタンをクリックした』というイベントが
メイン処理が終了するまでExcelに伝わらない
上の例では、人間が起こしたイベントが処理されないというものだが、
OSやExcel自身が起こしたイベントも処理できないと推測できる
質問者の例でいえば、Excelのでかいデータをスワップさせようとして
上手くいっていないのかもと推測した


125 :デフォルトの名無しさん:2011/03/04(金) 14:02:01.69
>>121
いやだから、手動でやると、コピー領域と貼り付け領域の形が違うため...
ってエラーになるんだが?


90 :デフォルトの名無しさん:2011/03/02(水) 23:26:44.73
splitに関してお聞きしたいことがあります。
セル内の最後の空白から前と後ろで分けたい場合
どのように記述すればよいでしょうか?


91 :デフォルトの名無しさん:2011/03/02(水) 23:43:33.04
>>90
InStrRevで場所を特定して分割すればいいんじゃないか?
Splitで返された配列の最後の一つ以外を繋ぎ直す手も無くはないけど。


95 :90:2011/03/03(木) 00:38:13.04
>>91
お陰さまで無事成功しました。
ありがとうございます。
ただ、こんなことで躓いていてはまだまだだなーと・・・


106 :デフォルトの名無しさん:2011/03/03(木) 15:11:28.92
とある文字列をA1からA1000までの中から検索するときに
forとifで比較しながら探すのって馬鹿なんでしょうか・・・


107 :デフォルトの名無しさん:2011/03/03(木) 17:55:24.96
forは使うけど、variable型配列に入れてInStrを使うかな


108 :デフォルトの名無しさん:2011/03/03(木) 18:04:11.98
>>106
個人的信条ですが、プログラムは正しく動くなら問題なしです^^
ただ、より簡単な方法もあります
ご参考まで
Sub test()
Dim FindCell As Range
'A1:A1000の中から最初に"xyz"が入力されたセルを探します
Set FindCell = Range("A1:A1000").CurrentRegion.Find(What:="xyz")
If FindCell Is Nothing Then
MsgBox "検索に失敗しました"
Else
MsgBox "見つかりました"
FindCell.Select
End If
End Sub


109 :108:2011/03/03(木) 18:14:32.29
追記
>>108の例ですと、部分一致の場合も見つかったと言いますので注意してください
完全一致のものを探すならば
Set FindCell = Range("A1:A1000").CurrentRegion.Find(What:="xyz", lookat:=xlWhole)
と、lookat:=xlWholeを指定の必要があります


110 :108:2011/03/03(木) 18:26:52.55
さらに追記
CurrentRegionは、不要ですね
Set FindCell = Range("A1:A1000").Find(What:="xyz", lookat:=xlWhole)
このサンプルは、『vba range 検索』で検索して見つけた
Office TANAKA - Excel VBA講座:セルの操作[セルの検索]
ttp://officetanaka.net/excel/vba/cell/cell11.htm
を参考に(というか、ほぼまる写し)しています


111 :デフォルトの名無しさん:2011/03/03(木) 20:37:06.02
Excel2007
Sub settest()
Const dataf As String = "test"
Dim datafile_path As String
datafile_path = "g:\data\"
Set ws3 = Workbooks(datafile_path & dataf & ".xlsx").Worksheets("test") ←エラー部分
Set ws3 = Nothing
End Sub
インデックスが有効範囲にないってエラーになります
ファイル及びtestシートの存在は確認しています
回避方法を教えてください


113 :デフォルトの名無しさん:2011/03/03(木) 21:37:58.59
>>111
Workbooksの使い方が間違っているとおもう
Workbooks(....)は既にオープンされている ブックにしか使えない
  Set wb = Workbooks.Open(datafile_path & dataf & ".xlsx")
  Set ws3 = wb.Worksheets("test")
又は
  Set ws3 = Workbooks.Open(datafile_path & dataf & ".xlsx").Worksheets("test")
後処理で ブックを クローズ(場合によってはセーブ)する事を考えると前者の方が良いと思うけど
wb.Close とかね


126 :デフォルトの名無しさん:2011/03/04(金) 14:55:06.80
Private Function hoge(c As Long) As Boolean
 If c > 0 Then
  hoge = True '------(a)
 End If
 If c < False Then
  hoge = False '------(b)
 End If
End Function
たとえばこういうプロシージャがあって、cが正の値だったとき
(a)の所で呼び出し元に戻ると思ってたのですが実際は
If c < False Thenまで処理が行きました
これが普通なんですか?自分はC言語のreturnと同じだと思ってたのですが


127 :デフォルトの名無しさん:2011/03/04(金) 14:57:30.68
訂正
自分は hoge = True はC言語の return 1; と同じだと思ってたのですが


128 :デフォルトの名無しさん:2011/03/04(金) 14:58:32.59
訂正
Private Function hoge(c As Long) As Boolean
 If c > 0 Then
  hoge = True '------(a)
 End If
 If c < 0 Then
  hoge = False '------(b)
 End If
End Function


129 :デフォルトの名無しさん:2011/03/04(金) 15:05:28.90
普通です
いやでしょうが
hoge = True '------(a)
Exit Function
と書いてください


130 :デフォルトの名無しさん:2011/03/04(金) 15:08:06.20
>>129
そうやるんですか!ありがとうございました!


131 :デフォルトの名無しさん:2011/03/04(金) 17:14:43.88
c == 0の時どうなるのか気になる・・・


132 :デフォルトの名無しさん:2011/03/04(金) 17:25:16.96
>>131
False
Booleanのデフォルトの値はFalseだから


133 :デフォルトの名無しさん:2011/03/04(金) 17:36:24.97
うん、VBAってhoge = c > 0って表記できなかったっけ?


134 :デフォルトの名無しさん:2011/03/04(金) 19:36:52.82
>>133
普通はそうする罠
Private Function hoge(c As Long) As Boolean
  hoge = c > 0
End Function
これなら>>131みたいな疑問は湧かないし、>>132みたいな知識がなくてもわかる


135 :デフォルトの名無しさん:2011/03/04(金) 19:37:38.27
>>133
聞く前に自分で試してくれないかねえ


136 :デフォルトの名無しさん:2011/03/04(金) 19:38:21.10
>>131
End Function
>>133
出来なきゃ困るだろw


137 :134:2011/03/04(金) 19:40:30.59
>>133
失礼
質問形じゃなくて、解答なのね


138 :135:2011/03/04(金) 19:41:19.70
ごめん
134でなくて135でした


141 :デフォルトの名無しさん:2011/03/05(土) 16:36:46.74
>133
これって (hoge=c)>0 って解釈されないのかな?
=は比較演算子としてより優先して代入演算子として解釈される?


142 :デフォルトの名無しさん:2011/03/05(土) 17:20:16.44
試せ
以上


143 :デフォルトの名無しさん:2011/03/05(土) 17:48:50.84
>>141
>これって (hoge=c)>0 って解釈されないのかな?
されない。
VBA は、C と違って、文を書くところに式は書けないなら hoge = c > 0 の
= は,代入演算子にしか解釈されない。


144 :デフォルトの名無しさん:2011/03/05(土) 21:55:27.65
>>142,143
試した
(Let)a=b=cだとb=cの比較結果をaに代入
if a=b=c then...だとa=bの比較結果とcを比較
代入文だと最初の=は代入演算子なのね
で、比較式として使うと比較演算子として解釈される
比較も代入も同じ記号だけど、文脈で完全に区別されるのね


156 :デフォルトの名無しさん:2011/03/07(月) 11:02:56.93
ファイル名に特定の文字列がある場合処理を分岐したいんですが
If ファイル名 = "特定の文字列*" Then
で引っかからないんですが何故でしょうか
特定の文字列* の所はファイル名そのものにすれば引っかかりますがそれでは意味ないし
どなたかお願いします


157 :デフォルトの名無しさん:2011/03/07(月) 11:17:25.64
>>156
If 文字列 Like "*ABC*" Then
以下のサイトより参照
ワイルドカードを使った文字列の比較
ttp://www.geocities.jp/masa7251/tips/vba/vba00002.html


158 :デフォルトの名無しさん:2011/03/07(月) 11:25:01.25
>>157
早いレスでとても助かりました
LIKEとかすっかり忘れてました。本当にありがとうございます。


162 :デフォルトの名無しさん:2011/03/07(月) 16:16:48.65
質問です
VBEで
セルA1を指定する
つもりで次のように入力し実行すると
Sub test()
Cells("1,2").Select
End Sub
なぜかセルL1が指定されてしまいます


163 :デフォルトの名無しさん:2011/03/07(月) 17:13:15.10
>>162
Cells(1, 1).Select
または
Range("A1").Select


164 :デフォルトの名無しさん:2011/03/07(月) 19:13:03.53
>>162は>>163で解決だが、Cells("1,2").Selectだと何でL1が選択されるんだ?
数字を色々変えてみるが理由が分からん。


165 :デフォルトの名無しさん:2011/03/07(月) 19:19:57.51
そうか、カンマが無視されてCells(12).Selectと同じってことだな。
Excel2003でCells("2,5,7").Selectなら多分A2だな。


166 :162:2011/03/07(月) 21:13:26.55
>>163
ありがとうございます
解決しました
>>162は一部数字が間違っています ("1,2")→("1,1")
>>165
試してみたら確かにA2になりました
端っこまでいって二列目に来たということですか?
もうひとつ質問です
今は無料のホームページを参考にしていますが
VBAを効率よく学習するにはやはり参考書を買ったり
教室に行ったりする方が良いのでしょうか?


167 :デフォルトの名無しさん:2011/03/07(月) 21:21:23.99
>>166
本を自宅で読むのなら、ホームページを見るのと変わらない
電車の中とか、空いている時間を活用するならそれでもいい
勉強する上で、一番大事なのは質問できる相手がいること
そういう意味では教室へ行くのがいいかもしれない


168 :デフォルトの名無しさん:2011/03/07(月) 21:35:09.18
>>166
そう端っこまでいって2行目に来たってことだ。
Range("B1:D2")(5).SelectならC2が選択される。
VBAの勉強なら教室行っても無駄だと思うなぁ。
とにかく何か作ってみることだな。
動けばよいって程度なら3か月もすれそれらしきものは作れる。


169 :デフォルトの名無しさん:2011/03/07(月) 21:49:48.65
下記ようなサンプル探しています。
Sheet1の一覧表から必要な項目だけを抜き出し
Sheet2のような形式の表に必要な項目を入れ込みたいと思います。
その時に
・納期が変わったら改ページ
の条件を付けたいと思いますが
VBAを使いSheet1から必要な項目だけをSheet2の表に入れ込むことは可能でしょうか?
ttp://uproda11.2ch-library.com/11288398.zip.shtml
DLキーは123です
宜しくお願い致します


170 :デフォルトの名無しさん:2011/03/07(月) 22:25:23.10
>>169
可能です。はい次の方ー


171 :デフォルトの名無しさん:2011/03/08(火) 18:02:38.53
dim d as new Scripting.Dictionary
は、
for each k in d.keys()

for each k in d.items()

ループさせるときにaddした順序が保たれることは保障されますか?
VBAに限らないとは思いますが。


172 :デフォルトの名無しさん:2011/03/08(火) 19:44:07.77
>>171
やってみりゃわかるだろ?
保障されるんだよ。
Dictionaryに限らずFor Eachじゃ順番が保障されないなんていうDQNもいるが、いままで順番を外れたのを見たことないわ。


173 :デフォルトの名無しさん:2011/03/08(火) 20:23:50.42
Microsoftの場合、そこら辺は大抵無難に作ってあるよね。
.NET互換のMonoとかは容赦なく保障しない作りになっているようだけど。
まあ、ドキュメントに記述されていない暗黙の了解があっさり覆されて
痛い目にあったりする事も間々あるから、慎重になる気持ちも解る。


174 :デフォルトの名無しさん:2011/03/08(火) 20:33:07.38
一応Microsoftの公式見解はFor Eachの順番は保障しませんってことじゃなかったっけ?
実際は順番通りだけどね。


181 :デフォルトの名無しさん:2011/03/09(水) 00:46:56.27
>>171
が保証される旨の記載ってどこかにないの?


184 :デフォルトの名無しさん:2011/03/09(水) 07:32:55.49
>>181
A Dictionary object is the equivalent of a PERL associative array.
WindowsSDKからのコピペだけど、PERLの連想配列と同等と書かれているから、
あくまで、キーと値のペアの配列として保持されていると考えて良いんじゃないかな。
よって、KeysやItemsも追加した順で返されると。
KeysやItemsの説明には、配列に含まれる全ての~を返す、としか書いてないけど。


175 :デフォルトの名無しさん :sage :2011/03/08(火) 22:52:52.89
知恵を拝借
Application.GetSaveAsFilename(initialfilename:="C:\test.txt"...
と指定し実行するとダイアログ窓がでて
ファイル名前後に "(ダブルクォーテーション)が入ってしまう
ファイル名欄に "test.txt" と出てしまう
"(ダブルクォーテーション)を取るにはどうすればいいのでしょうか?


176 :デフォルトの名無しさん :sage :2011/03/08(火) 23:11:44.61
コードを記述して完成したら F8 で一行ずつ確認して
正常に動くのを確認してから、マクロを実行したらエラーは
出なかったのですが、確認したのと違う動きになりました。

その後何度もF8で一行ずつ確認したのですが、正常に
動きました。なのでコードやセルの設定は間違っていない
と思うのですがこのようなことはあるのでしょうか??
また対処法があれば教えていただけないでしょうか?

分かりにくい文章ですみません。

i = .Range("A1").Value
If i <= 76 Then
.Range("B1:C1").Value = "20"
.Range("D1:F1").Value = "g/L"
Else: .Range("B1:C").Value = "-"
End If

このようなコードなのですが、
i<=76の時に 20 g/L
となるはずが - g/L
となってしまいます。


177 :デフォルトの名無しさん:2011/03/08(火) 23:32:21.96
>>175
すくなくともこっちで実験したらそうならなかった
環境をちゃんと書け
>>176
g/Lを消し忘れてるだけじゃないのか?


178 :デフォルトの名無しさん:2011/03/08(火) 23:44:33.23
>>177
いいえ、”20”が入るはずのセルに”-”と
ハイフンが入ってしまうのです。
ハイフンは ELSEの判定の時のはずなのに。


179 :デフォルトの名無しさん:2011/03/09(水) 00:37:53.49
>>178
いろいろコードが間違ってると思うが、とりあえず確実にELSEに行ってるなら
A1に入ってる値が数字じゃないと思われ
i = .Range("A1").Value のあとで、iの型確認してみ


180 :デフォルトの名無しさん:2011/03/09(水) 00:45:30.34
iを数値型で宣言してある?
>>179の言うような、評価が正しくされてない可能性がある
クイックビューかなにかで値を確認して初めて数字評価されて
デバッグ中だと正しく比較されるけど
通常の実行時は型の評価が遅延されてうまくいかない、って現象はある
確かめ方は、i <= 76 を i > 76にして、ifとelseの中身を交換してどうなるか見てみることだね


182 :デフォルトの名無しさん:2011/03/09(水) 01:14:19.92
>>179、180
iはDoubleで宣言しています。
ELSEに行っているのではなく、
If i <= 76 Then
.Range("B1:C1").Value = "20"
.Range("D1:F1").Value = "g/L"
の部分の"D1:F1"セルは"g/L"が表示されるのですが、
B1:C1セルのみ"20"が"-"になってしまい、TRUEとELSEの処理が
ごっちゃになっているのです。


183 :デフォルトの名無しさん:2011/03/09(水) 04:24:20.12
>>182
そもそもRange("B1:C")なんて言う指定はエラーだと思うが
コード晒すなら正確に。あとその前後も晒せ
とくにwithのあたりとか、ループしたりしてないかとか、ifのネスト無いかとか


185 :デフォルトの名無しさん:2011/03/09(水) 09:24:41.75
>>182
だからそのifあたりぼ書き方がおかしいかもしんないから検証しろっつってんだろカス
もう勝手にしろ


186 :デフォルトの名無しさん:2011/03/09(水) 12:35:33.47
>176
Else の後ろのコロンを抜いて、
改行してから次の文をかく。
VBのコロンはただの行ラベル。


187 :デフォルトの名無しさん:2011/03/09(水) 13:03:40.94
On Error Resume Nextが書いてあり、Elseの綴りが間違ってるに1000億ジンバブエドル。


188 :187:2011/03/09(水) 13:11:03.79
On Error Resume Nexは関係ねーか。
変数の宣言を強制してないでElseの綴りを間違ったんだな。


190 :175:2011/03/09(水) 20:32:54.40
分かりました

InitialFileNameで設定するファイルの拡張子と
FileFilterで設定する拡張子が異なる場合(ファイル名を test.txt にしてfilterを *.xlsにした場合など)
"(ダブルクォーテーション)が付くことが分かりました
スレ汚し失礼しました


191 :デフォルトの名無しさん:2011/03/09(水) 20:41:52.06
187だがOption Explicitも関係なしか。
Elseの綴りを間違って、ただの行ラベルになってしまったんだな。
綴りを間違わなければ行ラベルにはならんけど、どっちにしても>>186が言うように普通の書き方はにすべきだな。


192 :デフォルトの名無しさん:2011/03/09(水) 21:56:00.51
>>191
まあ落ち着けよwww


194 :デフォルトの名無しさん:2011/03/09(水) 23:24:44.66
182です。

昨日皆さんのアドバイスを頂いてからいろいろ検証してみました。
179さん、180さん、186さん、189さんおっしゃった通りに
すべて見直し、検証した結果上手くいきました。

原因としては他のモジュールで
.Range("B1:C1").Value = "-"
のコードがあり、記述途中での添削ミスでした。

こんな単純なミスを見逃し、みなさんを混乱させて
申し訳ありませんでした。

レスを下さった皆さんありがとうございました。
大変お騒がせいたしました。


193 :デフォルトの名無しさん:2011/03/09(水) 22:37:31.24
1ページに10行ある表があり印字データが1~10件の場合は
そのまま1ページに印字して10件以上のデータがあった場合は
改ページプレビュでデータ件数の最後までを1ページに印字する
設定は可能でしょうか?

もしくは件数に応じて表の行の高さを変更させることは可能でしょうか?
どうかお知恵を貸してください。お願いします。

195 :デフォルトの名無しさん:2011/03/09(水) 23:30:47.26
>>193
VBA使わなくても出きるような気がするが.....まあイイか
常に1ページにしたいなら
PageSetup オブジェクトで
 Zoom = False
 FitToPagesWide = 1
 FitToPagesTall = 1
で出来ると思うよ
後 行の高さを変更するには RowHeight プロパティを使う


196 :193:2011/03/10(木) 01:19:52.34
>>195
ありがとうございます。
手が空いたら実践してみようと思います。


214 :デフォルトの名無しさん:2011/03/18(金) 16:53:15.33
public const が良く分かりません
Public test as Range
Public const test = range("A1")
sub a()
test.value = 1
end sub
このように使いたいのですがうまくできません
どうすればいいでしょうか


215 :デフォルトの名無しさん:2011/03/18(金) 17:00:54.87
うまくできません って言われてもな
エラーが出るのか処理が思った通りに行かないのか
エラーが出るならそのメッセージを、
思った通りに行かないのなら現在どうなっていてどういうふうになってほしいのか
そういう情報を書け


216 :トリプルクリック:2011/03/18(金) 19:08:15.10
>>214
こうか?
Sub a()
Dim rangeA1 As Range
Set rangeA1 = Range("A1")
rangeA1.Value = 1
End Sub


232 :デフォルトの名無しさん:2011/03/20(日) 15:08:58.53
前スレで2003のエクセルマクロが2010で動かないのを質問した者ですが、
オリジナルページではマクロが動くことが分かりました。
使用するときはこのオリジナルページの新規作成ボタンを押して、
新たなエクセルファイルを作成するのですが、この新作成したマクロの
パスが新規作成ファイルのパスになっており、全てのパスをオリジナルに
設定しなおさなくてはなりません。設定せずに済むなにか良い方法はないでしょうか?


233 :デフォルトの名無しさん:2011/03/20(日) 16:11:11.10
>232
いまいちわからない。オリジナルページってなんだ?
あとパスを設定?書き換える?にしても、
なに用のパスを変更するかわからないと手出できない。
とりあえず、そのマクロを作った人に聞いたほうがいいんじゃないか?


242 :デフォルトの名無しさん:2011/03/23(水) 13:08:07.89
一つの音源を再生するのはできるんですが
一つの音源の音の高さを変えて再生することって可能ですか?


244 :デフォルトの名無しさん:2011/03/24(木) 11:47:08.99
beep音って同時に複数流せる?


251 :デフォルトの名無しさん:2011/03/26(土) 07:13:00.18
>>242>>244
MIDIデバイスをいじるといいぜ
昔自分用に作ったランダムに音を出すブック
http://www.death-note.biz/up/o/19433.xls


245 : 忍法帖【Lv=13,xxxPT】 :2011/03/24(木) 15:51:04.28
マウスホイールでアクティブセルの値を上下することはできますか?


246 :デフォルトの名無しさん:2011/03/25(金) 00:24:23.64
>>245
ホイールイベントをフックするぐらいしか思いつかん


247 :デフォルトの名無しさん:2011/03/25(金) 12:52:21.32
空白のセルではなく、セル内の空白行、例えばA1に
あいう
(空白行)
えおか
という文字があった場合、その空白行を消して
あいう
えおか
というように詰める事は可能でしょうか?
分かる方いましたら教えてください。お願いします。


248 :デフォルトの名無しさん:2011/03/25(金) 16:48:35.11
>>247
サンプル書いた
Sub Sample()
Worksheets("Sheet1").Columns("A").Replace What:=Chr(10) & Chr(10), Replacement:=Chr(10)
End Sub


249 :247:2011/03/25(金) 20:24:54.73
>>248
お答えくださってありがとうございます。
再度質問よろしいでしょうか?
Chr(10)がラインフィード文字というのは分かりましたが
何故Chr(10) & Chr(10)が空白行の検索ということになるのか
そしてReplacement:=Chr(10)に置換することによりどうして空白行が無くなるのか
いまいちわかりません。
それと、Cells(1,1)というようにして記述したい場合どのようになりますか?
よろしくお願いします。


250 :デフォルトの名無しさん:2011/03/25(金) 21:05:59.77
>>249
改行2個で空白行になるから、1個なら単なる改行になる。
A1のみならReplace関数でもいい。
With Cells(1, 1)
  .Value = Replace(.Value, vbLf & vbLf, vbLf)
End With
A列を置換なら
Range("A:A").Replace vbLf & vbLf, vbLf


254 :デフォルトの名無しさん:2011/03/26(土) 14:00:52.64
シートセルをVariantで配列に入れた後、その配列をRange変数に入れる方法ってないですか?
Application.WorksheetFunction.StDevとかに使うためにやりたいです


255 :デフォルトの名無しさん:2011/03/26(土) 14:33:21.31
>>254
普通に出来るだろ


256 :デフォルトの名無しさん:2011/03/26(土) 14:34:23.40
だからその普通がしりてーんだよボケカス


257 :デフォルトの名無しさん:2011/03/26(土) 14:51:21.56
>>254
サンプル書いた
Sub Sample()
Dim WS As Variant
Dim R As Range
Set WS = ActiveSheet
Set R = WS.Cells
End Sub


258 :254:2011/03/26(土) 15:06:42.44
すいません>>256は自分ではない別の人なので
>>255>>257
ありがとうございました!


274 :デフォルトの名無しさん:2011/03/27(日) 20:07:30.07
エクセルマクロ初心者です。誰か教えてください。
以下のマクロがあったとします。
【例①】----------
Sub テスト1()
   test1-1行目
   test1-2,3…n行目
End Sub
Sub テスト2()
   test2-1行目
   test2-2,3…n行目
End Sub
Sub 一括処理()
   テスト1
   テスト2
End Sub
----------
Sub 一括処理()を実行した場合、『test1-1行目、test1-2,3…n行目、test2-1行目、test2-2,3…n行目』という順番で実行されますよね?
Sub 一括処理()で例②のようなプログラム以外に『test1-2,3…n行目、test2-2,3…n行目』のみを実行させる方法はありますか?テスト1、2にIF文を付けたりして試してみたのですが自分の実力ではダメでした。
以下のようにプログラムすれば簡単なのですが…
・実際のマクロは行数がものすごく多い。
・テスト1、テスト2、一括処理のそれぞれで実行させたい。
・例②のようにプログラムするとテスト1、テスト2で変更がかかったときにミスにつながる。
【例②】----------
Sub 一括処理()
   test1-2,3…n行目
   test2-2,3…n行目
End Sub
----------
良い方法を教えてください。お願いします。


275 :デフォルトの名無しさん:2011/03/27(日) 20:19:40.09
>>274
引数(ひきすう)を使うといいよ
こんな感じで、何行目から始めるか指定する
Sub テスト1(x)
   test1-x…n行目
End Sub
Sub テスト2(y)
   test2-y…n行目
End Sub
Sub 一括処理()
   StartLine = 1
   テスト1(StartLine)
   テスト2(StartLine)
End Sub
一括処理の中の最初の行を「StartLine = 2」にするだけで、処理の範囲を変えることができる


357 :デフォルトの名無しさん:2011/04/01(金) 10:14:53.51
ユーザー定義関数について教えてください。
個人用マクロブックにユーザー定義関数を書いているんですが
実際にそのマクロを使用するワークシート内で関数を実行しようとする場合
=個人用マクロブック!関数名
という風にユーザー定義関数の指定を個人用マクロブックの指定も含めて
行わなければname?となってしまうんですが、個人用マクロブックの指定を
省略することができるような設定方法などないでしょうか。


358 :デフォルトの名無しさん:2011/04/01(金) 10:21:24.50
標準モジュールにPublic Functionで書いてる?


360 :デフォルトの名無しさん:2011/04/01(金) 12:31:43.52
レスありがとうございます。
Publicをつけていなかったのでつけてみたんですがやはりマクロブックの
指定をしないとname?になってしまいます。
標準モジュールには記述しています。


418 :デフォルトの名無しさん:2011/04/05(火) 07:10:56.44
Inputboxでセル範囲を入力してそれをFor Nextで
一つずつ下げるのを繰り返したいのですがエラー(1004)に
なります。
どこが間違っているかご指摘してもらえないでしょうか。
Dim i,d As Integer
d = InputBox("抽出する日数を入力してください", "日数")
If d = "" Then Exit Sub
For i = 0 To 10
☆ ActiveSheet.Range(Cells(2, 4), Cells(2, d)).Offset(i, 0).Select
Next
☆のところでエラーになります。


419 :デフォルトの名無しさん:2011/04/05(火) 07:39:47.18
>>418
☆以前に
If d = "" Then Exit Sub
でエラーだろ
整数型と文字列の比較演算してるんだから
変数dに列番号の有効範囲値(2003以前なら1~256、2007移行なら1~16384)が
入っていれば☆自体はエラーにならないよ
Ifでエラーにならずに☆でエラーになるなら、おそらく実行時に変数dにAs Integerを付けてなかったんだろう
変数の型指定無し、つまりVariant型だと、InputBoxに数値の入力しても、それは数値ではなく数字文字列扱い
つまりCells(2, "10")みたいなことをしているのと同じなのでエラーになる
まあ簡単に言うと「d = ""」を「d = 0」にすれば良し
InputBoxでキャンセルした場合に返される値は""ではなくEmptyなので、これが数値型に代入されれば0になる
あと、その書き方だとiはInteger型にならないぞ
Dim i As Integer, d As Integer


420 :デフォルトの名無しさん:2011/04/05(火) 07:44:02.64
またまた壮大な釣りが…


421 :デフォルトの名無しさん:2011/04/05(火) 07:55:14.89
>>418
d = Val(InputBox("抽出する日数を入力してください", "日数"))
If d = 0 Then Exit Sub
シートのセルが結合されてない?


422 :デフォルトの名無しさん:2011/04/05(火) 07:58:03.67
>>419
それだけだとInputBoxに数値以外の物を入力した時にエラーで止まる


423 :デフォルトの名無しさん:2011/04/05(火) 08:11:56.65
VBAや昔のVBでは、
Dim i,d As Integer
でIntegerになるのはdだけだぞ


424 :418:2011/04/05(火) 08:19:28.82
>>419
ご指摘ありがとうございます。
また、夜試してみます。
>>421
セルは結合してないです。
そんなやり方もあるんですね。勉強になります!


425 :デフォルトの名無しさん:2011/04/05(火) 09:00:11.06
>>422
それは419の回答の問題ではなく、418に最初からある問題だから、419に言うのは筋違いかと。


426 :デフォルトの名無しさん:2011/04/05(火) 10:12:24.28
そもそもその宣言だとdはval型だろ


427 :デフォルトの名無しさん:2011/04/05(火) 10:17:16.65
その宣言ってどの宣言?
iがval型なのはあるが、dがval型なのは見あたらないんだが


428 :デフォルトの名無しさん:2011/04/05(火) 12:33:36.35
ああ、間違えたiか
dがintだな
自動初期化だとdに0が入るから、if文はスルーされる
セル(2,0)が参照されたエラーだな


429 :デフォルトの名無しさん:2011/04/05(火) 12:49:23.14
恥ずかしい奴


430 :デフォルトの名無しさん:2011/04/05(火) 13:33:13.16
If chk_日付.Value = True Then
Else: txt_日付.Value = ""
End If
If chk_金額.Value = True Then
Else: cmb_金額.Value = ""
End If
If chk_担当.Value = True Then
Else: txt_担当.Value = ""
End If
あと5項目ほど続くのですが、もっとコンパクトな記述方法はないでしょうか?
Arrayを使おうとおもったけど、うまくいきませんでした。


431 :デフォルトの名無しさん:2011/04/05(火) 13:39:25.56
>>430
疑似コントロール配列を使う
or
Controlsコレクションを使う


432 :デフォルトの名無しさん:2011/04/05(火) 14:42:23.50
>>429
///
>>430
1.コントロール情報を配列に格納して回す
2.判定と処理が複数回あるなら別コードに書いて呼び出す
3.全部のコントロールを対象にして後で修正しないならfor~each使う


433 :デフォルトの名無しさん:2011/04/05(火) 14:49:46.73
Else: cmb_金額.Value = ""

Else: txt_金額.Value = ""
の間違いでない限り、まとめるのは無理
あと、False~ThenじゃなくてTrue~Elseになってるのが気持ち悪い
Elseのあと改行せずに : を書いてるのが気になる
いちいち= Trueを書くのも無駄っぽい


434 :デフォルトの名無しさん:2011/04/05(火) 14:59:37.65
> Else: cmb_金額.Value = ""
> が
> Else: txt_金額.Value = ""
> の間違いでない限り、まとめるのは無理
無理じゃないよ
VB6のコントロール配列だと、コントロール種は揃えなきゃならないけど
VB6だろうとVBAだろうと、クラスとコレクションで作る疑似コントロール配列なら
コントロール種が揃ってなくてもまとめることは可能


441 :デフォルトの名無しさん:2011/04/05(火) 19:13:40.86
A1に"L3"と入力されていて、L3に文字を入力したいです
VBAでINDIRECT関数を使うにはどうしたらいいですか?


442 :デフォルトの名無しさん:2011/04/05(火) 19:39:13.70
>>441
Range(Range("A1").Value).Value = "hage"


443 :デフォルトの名無しさん:2011/04/05(火) 19:57:08.90
>>442
ありがとうございます


450 :418:2011/04/05(火) 22:35:10.96
皆さんに指摘されたことを試してみたけどやはり
ActiveSheet.Range(Cells(2, 4), Cells(2, d)).Offset(i, 0).Select
のところで実行時エラー1004になります。
ActiveSheet.Range(Cells(2, 4), Cells(2, 10)).Select
でも試してみたのですがやはり1004エラーになりました。
同じマクロで
For i = r To 10
ActiveSheet.Columns(i).ClearContents
Next
と不要な列の内容を削除するコードは正常に動いています。
どこがいけないのでしょうか??


452 :デフォルトの名無しさん:2011/04/05(火) 22:57:19.31
>>450
釣りかもしれんけどあえて エスパーしてみる
そのコードはシートモジュールに書いてない?
例えば
Sheet1のシートモジュールにコードを書いていて
Sheet2をActiveにした状態でそのコードを実行してるとか?


453 :デフォルトの名無しさん:2011/04/05(火) 23:00:42.51
>>450
いまひとつ何がしたいか分からないけど、
私の環境ではInputBoxで「10」を入力した場合、
Range(D2:J2)が最初に選択されて
Range(D12:J12)まで一行ずつずれていく動作になっているよ


454 :デフォルトの名無しさん:2011/04/05(火) 23:06:21.43
>>450
こんな感じになってる?
あと考えられるのは、少し前のExcelでInputBoxに257以上を指定してるとかだけど。
Private Sub xxx()
  Dim i As Integer
  Dim d As Integer
  
  d = InputBox("抽出する日数を入力してください", "日数")
  If d = 0 Then Exit Sub
  
  For i = 0 To 10
  ActiveSheet.Range(Cells(2, 4), Cells(2, d)).Offset(i, 0).Select
  Next
End Sub


455 :デフォルトの名無しさん:2011/04/05(火) 23:07:18.83
>>450
ActiveSheet.Range(Cells(2, 4), Cells(2, 10)).Select
が1004エラーになるというのは、
コード以外の問題じゃないのか?
イミディエイトウィンドウに書いても実行できないの?


456 :デフォルトの名無しさん:2011/04/05(火) 23:09:35.15
>>452
その通りでした。
標準モジュールに記述し直したら動きました。
For i = r To 10
ActiveSheet.Columns(i).ClearContents
Next
↑の部分が正常に動いていたので見落としていました。
勉強不足を痛感します。
ありがとうございました。


457 :デフォルトの名無しさん:2011/04/05(火) 23:24:46.02
>>453、454、455
書き込む前にリロードしていませんでした。
標準モジュールに記述したら、無事動きました。
dでセル範囲を指定して、iで下方向に検索しようと思い
前段階として、セルの選択ができるか試したかったのです。
レス下さった皆さんありがとうございました。


458 :452:2011/04/05(火) 23:39:31.48
>>457
余計なお世話かもしれないけれど
Rangeオブジェクト(RangeとかCellsとかその他)を扱う時は
ケースバイケースだけど
シートを明示した方が今回のような凡ミスは防げると個人的には思う
(過去にも 同様なエラーで質問された方が いた気がする)
ActiveSheet.Range(ActiveSheet.Cells(2, 4), ActiveSheet.Cells(2, 10)).Select
とか
With ActiveSheet
.Range(.Cells(2, 4), .Cells(2, 10)).Select
End With
とかならシートモジュールでも問題なかったハズ


459 :デフォルトの名無しさん:2011/04/05(火) 23:44:18.40
>>444
クラスモジュール使ったらできたよ
でも、3組程度の個数で、enabled の切り替え程度の単純な処理内容なら、
>>444のコードのようにひとつずつ記述したほうがいいように思う


460 :デフォルトの名無しさん:2011/04/06(水) 00:12:20.49
>>458
なるほど。ありがとうございます。
今後の参考にさせていただきます。


480 :デフォルトの名無しさん:2011/04/08(金) 17:02:29.82
A B C D  E
0 0 44 55 66    A1が0の場合C3の値をA1に入れる
0 0 44 55 66    A1が1の場合D3の値をA1に入れる
0 1 44 55 66    A1が2の場合E3の値をA1に入れる
1 1 44 55 66          : 
1 1 44 55 66          :
1 1 44 55 66          : 
2 1 44 55 66    A1が100の場合
2 2 44 55 66
このようにして100まで分岐させたいのですが、どうすればいいでしょうか?
Excel2000です。


481 :デフォルトの名無しさん:2011/04/08(金) 17:54:49.93
>>480
Dim a As Integer
If IsNumeric(Cells(1, 1).Value) Then
    a = CInt(Cells(1, 1).Value)
Else
    a = -1
End If
Select Case a
    Case 0 To 100
        Cells(1, 1).Value = Cells(3, a + 3).Value
End Select
邪魔くさいんで解説はしない
正常に動いてないようならお前の説明が悪い


482 :480:2011/04/08(金) 19:15:02.31
ちゃんと動きました
ありがとうございます

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2011年04月18日 17:42