トップページtech
1001コメント417KB

Excel VBA 質問スレ Part33

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2013/10/17(木) 22:04:40.64
ExcelのVBAに関する質問スレです

                   ___
       ___      /____ヽ      ____
      /____\    | |´・ω・`| |    /___ヽ
      .l |´・ω・`|  ニX二 . ̄ ̄ ̄  二X二  |´・ω・`| l 俺たちに任せろ
      !、 ̄ ̄ ̄  ヽ   |       |    /    ̄ ̄ ̄/
       ヽ_/ヽ、  ヽ__)  \__/\_/.   /_/  ノヽ_/
             ̄                ̄ ̄

前スレ
Excel VBA 質問スレ Part32
http://toro.2ch.net/test/read.cgi/tech/1381151717/

このスレはコード書き込みOKです。
作成依頼もOKですが、作成依頼限定ではありません。

コードが嫌な人はこちらのスレへ
http://toro.2ch.net/test/read.cgi/tech/1381151995/l50
0631デフォルトの名無しさん2014/06/05(木) 16:39:59.43ID:I2VjvGe/
>>623
UNIX系だと、行区切りの文字列では、sort + uniq が定番
uniqは連続した重複行を、1行にまとめる
そのため、最初にsortする

>>627
正規表現なら、[あ|い|う]{1,4}

[あ or い or う]が、1回以上、4回以下
0632デフォルトの名無しさん2014/06/05(木) 16:54:30.09ID:AERMy3Ek
>>630
具体的な用例まで助かります。
他にもいくつか加えたい条件もあるので、>>630をヒントと言いますかベースに自分で定義してみたいと思います。
有難う御座いました。
0633デフォルトの名無しさん2014/06/05(木) 16:58:50.71ID:U+cU1pOh
>>631
それだと"あいおいう"に対応できない
俺の解釈では「あいう」は不連続でも個数さえ合っていれば条件に一致する
06346312014/06/05(木) 18:16:58.07ID:I2VjvGe/
不連続で、1〜4個か

意外に難しいわい。頭を使わせよるw
0635デフォルトの名無しさん2014/06/06(金) 00:01:51.20ID:Yt2QH+fK
ちょいと質問
CopyとかPasteを使ってると時々「貼り付けられないよ!」ってエラーが出る

このエラーはactiveSheet.Range("A1").Copyとか書いてたら高確率で出るんだけど
WorkSheet("シート1").Range("A1").Copyって感じでシート名をちゃんと指定してやると
うまく処理される
これってOffiiceの仕様か何かなの?
なんかExcel2003だけでなく2010でも似たような現象が出たんだけど
0636デフォルトの名無しさん2014/06/06(金) 00:37:42.95ID:nBXq1INX
copyで張りつけられないってエラーは出ないと思うんだが
コピー時にエラーがでるのか貼り付け時にエラーがでるのか?

ActiveSheet指定したときに、実際は何が対象になってるか確認してみろよ
実際にコピーされているものが何かも確認してみろよ
0637デフォルトの名無しさん2014/06/06(金) 02:49:29.53ID:ufTytRJw
Private Const clsName As String = "aaa.cls"

Sub test()
 Dim obj As Object
 Set obj = New clsName
End Sub

こんな感じで変数名とかクラス名を一般化する方法ってありますか?
0638デフォルトの名無しさん2014/06/06(金) 05:12:25.67ID:Yt2QH+fK
>>636
ごめんそれで合ってる>貼り付け時にエラーがでる
.Copy後に.Pasteをしてやるとエラーが出るんだ
確認したらActiveSheetで指定しているシート名は「シート1」になってた
なぜか「ActiveSheet」と書くとダメで「WorkSheet("シート1")」と書くと
うまくいくんだよな
0639デフォルトの名無しさん2014/06/06(金) 06:03:40.15ID:2p7Hju+q
>>638
未確認だけど

.Copy
DoEvents
.Paste

でうまくいく場合もあるっぽいよ
どうもCopyメソッドはシステムに処理を投げたあと、完了する前に次に進むっぽい
だからクリップボードのアクセスがかち合ってPasteで失敗する
0640デフォルトの名無しさん2014/06/06(金) 10:38:05.93ID:pY4qYt1M
ユーザーフォームのテキストボックスにBeforeUpdateというイベントがありますが
テキストボックスを多数使うので、クラスとコレクションを使って疑似コントロール配列ししようとしたところ

Private WithEvents TextBoxControl As MSForms.TextBox

の宣言では、BeforeUpdateイベントが使えません。
(他にもAfterUpdate、Enter、Exitイベントが、ユーザーフォームモジュールでは使えるのにクラスでは使えない)

この型でユーザーフォームのテキストボックスを代入することは出来ますし、Changeなどのイベントは取れるのですが
クラス内でBeforeUpdateイベントを取得するには、どうすれば良いですか?
0641デフォルトの名無しさん2014/06/07(土) 03:36:29.21ID:Jb4BFO2L
>>637
そんなもんない
0642デフォルトの名無しさん2014/06/07(土) 05:13:53.67ID:lWh6G2t5
>>637
リフレクションのことを言ってるのかな。
なら、残念。クラスや変数には存在しないな。
ただ、関数だったらスレチになるけど、API、Addressof、コールバックあたりでググれば
幸せになれるかもしれないしなれないかもしれない。
0643デフォルトの名無しさん2014/06/07(土) 05:48:21.20ID:iV9P9+UY
あるプロシージャ内で変数(2次元配列)を3つ使用しています。
今は3つですが今後増える可能性があります。
A個の変数を宣言することができるのでしたら汎用性が高まるのですが可能ですか?
(例:A=5ならArray_1、Array_2、Array_3、Array_4、Array_5の5つを宣言する)

今は2次元の配列を3次元にすることも考えたのですが、
今のコードでは、2次元配列はWorksheetFunction.Max(Array_1)のような
配列を処理できる関数に突っ込まれていたりして2次元を3次元にすると色々問題が出てきそうです。

どのように変数を宣言したらよいのかがわかりません。アドバイスをお願いします。

注)今ある3つの2次元配列サイズは(1 to 50, 1 to 50) as Doubleです。今後変数が増えたとしても、各変数は2次元で50×50で同サイズです。
0644デフォルトの名無しさん2014/06/07(土) 06:21:36.64ID:lWh6G2t5
>>643
2次元の配列宣言をクラスで行うようにして、
そのクラスを生成したものをコレクションなりディクショナリなりに突っ込んで
使えばいいんじゃないかな。
多分、3つどころか1つで済むとおもうよ。
06456432014/06/07(土) 06:39:19.09ID:iV9P9+UY
>>644
レスありがとうございます。ただ、クラスとかコレクションとかディクショナリとか難易度高いです。レスの内容が理解できません。
クラスについては、メソッドやプロパティをオブジェクトに実装させるための設計図?というぐらいの知識しかありませんし、
ディクショナリは重複のない組み合わせを得るのに何度か使ったことあるぐらいです。
クラス内で配列を宣言?クラス内なら変数Aの数だけ配列を宣言できるということ?
プロシージャ内で宣言するのとどう違う??宣言した変数は引数として渡す?それともPublic変数?
わからないことだらけです。調べてみます。
0646デフォルトの名無しさん2014/06/07(土) 08:02:44.68ID:DbL3YGfr
>>643
難しく考えず、配列の配列でいいんじゃないか
Variantの配列作ってそれに突っ込め
0647デフォルトの名無しさん2014/06/07(土) 08:31:36.91ID:lWh6G2t5
>>645
調べるならVBAよりVBで調べた方が分かるかも。
面倒臭いならいっそのこと、シートを配列に見たてて使ってしまえば?
普段見てるシートも、シートと言うクラスのインスタンスに過ぎないから、考え方は同じだよ。
06486432014/06/07(土) 23:06:01.41ID:iV9P9+UY
>>646>>645
レスありがとうございます。配列の要素に配列を代入できるのですね。知りませんでした。
Dim testArray as Variant
ReDim testArray (1 to intA)
そしてTestArrayの各要素に(1 to 50, 1 to 50)の2次元配列を無事に代入できることを確認しました。

今のコードには、セルに書出すための2次元配列が大量にあり整理できずに困っていましたが、
配列の配列やコレクションを使ってスッキリできそうな気がしてきました。
短期的には配列の配列で解決できそうです。長期的には>>644を理解しつつトライしてみます。
アドバイスありがとうございました。勉強になりました。
それにしても配列操作する際のVariantの万能感は半端ないですね。
0649デフォルトの名無しさん2014/06/08(日) 01:07:33.31ID:IWDW3tNj
Variantは機能的にはかなり万能で便利だけど処理は重いしメモリも大量に食うという欠点が
0650デフォルトの名無しさん2014/06/08(日) 01:16:28.64ID:GjVpljzs
50×50のDouble配列に比べたら、バリアントのオーバーヘッドなんて誤差の範囲だと思うが
0651デフォルトの名無しさん2014/06/08(日) 10:29:13.59ID:SjxXj1KS
今時のコンピュータリソースからみたら Variant のオーバーヘッドは問題になることはほぼないだろうね
むしろ Variant の万能感の方が問題かと
0652デフォルトの名無しさん2014/06/08(日) 11:40:36.05ID:IWDW3tNj
パソコンにどんだけリソースがあってもVBAの方で利用できるメモリが制限されてるという

たとえば、ワークシートに巨大な表があって、Integer型の配列にFor Nextで1個ずつコピーなら入るのに
Variant配列に一気に読み込もうとするとメモリ不足で無理とか
0653デフォルトの名無しさん2014/06/08(日) 12:24:09.79ID:SjxXj1KS
>>652
具体例よろ
32KB/64KB 制限の話じゃないよね
0654デフォルトの名無しさん2014/06/08(日) 14:01:22.44ID:AzMImLSv
OSのリソース切れとかもうね
0655デフォルトの名無しさん2014/06/09(月) 08:28:18.70ID:2ZoqHH1s
>>652
それは、ホントに読み込みでエラーなのか?

Integerの配列なら割り当てれるがVariantの配列は割り当てられない
っていうなら、メモリ制限の問題で有りうるだろうが

>パソコンにどんだけリソースがあってもVBAの方で利用できるメモリが制限されてるという
これそのものに間違いがなくても、不適切な例をだすと説得力がなくなるぞ
06566402014/06/09(月) 08:46:53.03ID:YJn9ltJZ
.
>>640も宜しくお願いします。
0657デフォルトの名無しさん2014/06/09(月) 09:44:16.22ID:2ZoqHH1s
>>656
オブジェクトブラウザで見ると
BeforeUpdateとかはTextBoxで実装されてなさそう
無理なんじゃないかな
0658デフォルトの名無しさん2014/06/10(火) 01:36:44.07ID:FAZAoJi3
ソースコード中にあるコメントの行だけ表示/非表示で切り替える方法ないですか?
0659デフォルトの名無しさん2014/06/10(火) 02:07:04.29ID:hc4LiDN+
ないです
06606402014/06/10(火) 03:57:59.03ID:ZdnvVnA2
>>657
そうなんですよ
MSForms.TextBoxには、BeforeUpdateが実装されてないんです

しかし、

Dim tb As MSForms.TextBox
Set tb = UserForm1.TextBox1

は通りますが

Dim tb As TextBox
Set tb = UserForm1.TextBox1

は型不一致でエラーになるように、TextBoxと言ってもいろいろあるようで
MSForms.TextBoxは、どうやらワークシート上に配置するコントロールのTextBoxのことで
ユーザーフォーム上のTextBoxを代入してもエラーにこそなりませんが、本来、適した型では無いようなのです

ワークシート用のTextBoxには元からBeforeUpdateが実装されていないので
ワークシート上のTextBoxでBeforeUpdateを取るのが無理なのは解りますが
ユーザーフォーム用のTextBoxには、間違いなくBeforeUpdateが実装されていて、実際に使えているので
ワークシート用のTextBox型ではなく、ユーザーフォーム用のTextBox型で宣言すれば
機能としては間違いなく実装されている以上、BeforeUpdateも取れるのではないかと思うのですが
その正しい型がどれなのかがわかりません
0661デフォルトの名無しさん2014/06/10(火) 05:54:47.60ID:DoT4XX20
>>660
とりあえずオブジェクトブラウザの使い方覚えて
標準的な参照設定の範囲ではTextBoxはMSForms.TextBoxしかないと思うけど

ユーザーフォーム用のTextBoxは MSForms.TextBox
オブジェクトブラウザで見る限り、BeforeUpdateはTextBoxに直接定義されていない
TextBox以外の所で定義されています(おそらくMSForms.Controlからの継承)

本来はMSForms.Controlの変数を用意してそれにTextBoxをセットすれば良いのですが
残念なことにControlはイベントソースとしては公開されてないようです(WithEvents付きで宣言できない)

ということでVBAではできません
素直に違う方法を考えましょう
0662デフォルトの名無しさん2014/06/10(火) 09:29:36.71ID:DruWYpJa
VBAで配列の行列を入れ替えるためにWorksheetFunction.Transposeを使用していますが特定の条件で問題が発生します
問題の発生するコード(サンプル)を貼り付けておきます。実際のコードはこれとは異なります。
このサンプルコードは正常に動作するのですが、"i mod100"を"i mod 10000"に変更すると問題が出てきます(このときcnt=1となります)。
TestArrayという二次元配列が、Transposeした後には一次元配列になってしまっています。

実際のコードではTranspose後の配列の値を読み出すのですが、TestArrayが二次元配列であるという前提で読みだしていますが、
cnt=1のときだけTranspose後のTestArrayが一次元配列になっているためエラーとなります。

cnt=1のときとそれ以外のときで場合分けすれば問題は解決するのですがスマートではないので躊躇しています。
何か美しい解決方法はないものでしょうか?

'**********************************************************
Sub test()

Dim i As Long, cnt As Long, TestArray As Variant
ReDim TestArray(1 To 3, 1 To 200) '余裕を持って200まで準備

For i = 1 To 10000
If i Mod 100 = 0 Then
cnt = cnt + 1 'カウンター(条件を満たした数)
TestArray(1, cnt) = 1: TestArray(2, cnt) = 2: TestArray(3, cnt) = 3
End If
Next i

ReDim Preserve TestArray(1 To 3, 1 To cnt) '不要なところを捨てる
TestArray = WorksheetFunction.Transpose(TestArray)

End Sub
'**********************************************************
0663デフォルトの名無しさん2014/06/10(火) 20:29:07.13ID:8dL1hbUs
AAA.xlsのデータを開いた状態で

Workbooks.Open Range("A1").Value & ".xls"
If Range("A2").Value > 0 Then Sheets("sheet1").PrintOut Copies:=Range("A2").Value


AAA.xlsを開き、そのA1に書かれてるBBB(という名の).xlsをA2にある数分だけ印刷したいマクロを組みたいのですが、
上記のだとBBB.xlsのA2を参照しようとしてしまいます。
どうすればAAA.xlsファイルのA2を参照できるでしょうか?
0664デフォルトの名無しさん2014/06/10(火) 21:30:20.37ID:hc4LiDN+
>>663
枚数 = Range("A2").Value
Workbooks.Open Range("A1").Value & ".xls"
If 枚数 > 0 Then Sheets("sheet1").PrintOut Copies:=枚数
0665デフォルトの名無しさん2014/06/10(火) 21:40:11.81ID:UIbglvLX
>>664

よければ>>663がダメで>>664ならいける理由を
説明願いたい
0666デフォルトの名無しさん2014/06/10(火) 21:43:02.84ID:QPzsyhTi
オープンしたらbbbがActiveになるだろ?ブックとシート省略しちゃだめ
0667デフォルトの名無しさん2014/06/10(火) 21:45:17.34ID:UIbglvLX
>>666
なるほど やっと理解できた
06686632014/06/11(水) 21:44:28.79ID:FYp71EYH
遅れましたが>>664さんありがとうございます

何度も申し訳ないですが

枚数 = Range("A2").Value
If 枚数 > 0 Then Workbooks.Open Range("A1").Value & ".xls"
If 枚数 > 0 Then Sheets("sheet1").PrintOut Copies:=枚数


Ifの条件を
枚数 = 1〜65535(印刷で設定可能な数)
に変えたいです
具体的な書き方を教えていただけないでしょうか
0669デフォルトの名無しさん2014/06/11(水) 21:58:07.88ID:FYp71EYH
If 枚数 >= 1 And 枚数 <= 65535 Then

こんなで良いのでしょうか
0670デフォルトの名無しさん2014/06/11(水) 22:11:11.04ID:GbTJWusP
「0より大きい」で不都合あるとは思えないんだが
0671デフォルトの名無しさん2014/06/11(水) 22:17:48.49ID:FYp71EYH
>>670
そんな簡単なのがあったんですね
そっちにします ありがとうございます
0672デフォルトの名無しさん2014/06/11(水) 22:19:55.78ID:FYp71EYH
ああ
初めから0より大きいだったんですね
申し訳なかったです
0673デフォルトの名無しさん2014/06/12(木) 02:42:30.17ID:efyo1JwZ
ファイル1・・・マクロ1
ファイル2・・・マクロ2

ファイルを単独で開いている時には、マクロ1とマクロ2は正常に動きます。
ファイルを二つ開いた状態では、マクロ1とマクロ2は正常に動きますがマクロが終わるまでに異常に時間がかかります。
マクロ1にもマクロ2にも、ワークブック名を省略した記述があり(worksheets(1).cells(1,1)のように)、これが原因だと思い"thisworkbook."を付加するなどして修正しました。
しかしマクロ終了までに時間がかかるという問題は解決しないままです。
原因として何が考えられますか?
0674デフォルトの名無しさん2014/06/12(木) 02:53:44.23ID:Ip/6+VhQ
>>673
リソース不足
0675デフォルトの名無しさん2014/06/12(木) 19:29:45.18ID:JGtl8L6J
日別の購入データの通し番号から、マスターを参照してジャンル分けして、ジャンルごとの合計金額を出したいです。

http://light.dotup.org/uploda/light.dotup.org28231.png

データはこのような画像の通りにシート3つに分かれて存在しています。
どのようなマクロを組めばいいかお教え願いたいです。
ジャンルごとに変数というものを持たないといけないのでしょうか?
実際は母が使うので、ボタン一つで出来るのだとありがたいのですが・・・
大変面倒な質問ですが、お願いします
0676デフォルトの名無しさん2014/06/12(木) 19:50:40.35ID:JgOg9e9B
vlookupとsumifで出来ないか?
0677デフォルトの名無しさん2014/06/12(木) 20:24:31.20ID:JGtl8L6J
>>676
一度マスターでジャンルを確認しないといけないので、どうすればいいのかわからないのです
マクロでぽんと出来ると嬉しいのですが
0678デフォルトの名無しさん2014/06/12(木) 20:50:37.37ID:A1ckDykJ
真ん中の緑のデータを元に、key:通し番号 value:(ジャンル名、合計値)の配列 で辞書を作る
左の黄色のデータを上から処理する
処理内容は、辞書を通し番号で索引してvalueの配列を取り出して、合計値に値を合算して、辞書に戻す
最後に辞書の全部のvalueの配列の内容を、右の赤のところに書き出す
0679デフォルトの名無しさん2014/06/12(木) 20:58:48.89ID:leNeVPHt
>>675
ピボットで一撃で片付きそうな気もするけど、
マクロで組むならその形式であれば、それらのシートをテーブルに見たてて、
SQLを投げて、レコードセットに取得した値を他のシートに展開するのが
ちまちまロジック組むより手っ取り早いかな。
0680デフォルトの名無しさん2014/06/12(木) 20:59:14.04ID:JGtl8L6J
>>678
本当に面倒で申し訳ないのですが、そのプログラムを教えてくださいませんでしょうか
辞書を作る以外で方法はないでしょうか
0681デフォルトの名無しさん2014/06/12(木) 21:01:22.38ID:A1ckDykJ
>>680
自分でやる気ゼロかw

辞書作らないなら黄色ところに作業列を追加してジャンルを振ってからピボットか何かで集計するとかじゃね
0682デフォルトの名無しさん2014/06/12(木) 21:19:47.42ID:leNeVPHt
ま、いいんじゃない?
いくつかキーワードも挙がったし。
後は自分で調べるか、コード晒してくれる優しい人を待つか。
ただ、この程度のものであれば自分で調べて組んだ方が早いだろうけどね。
0683デフォルトの名無しさん2014/06/12(木) 21:23:44.62ID:paP2EzQv
できないやつらが上から目線w
0684デフォルトの名無しさん2014/06/12(木) 21:26:40.23ID:leNeVPHt
>>683
じゃ、出来るあなたがコード晒してあげたら?
0685デフォルトの名無しさん2014/06/12(木) 21:26:43.13ID:FQgQ1zJa
この程度のものならコード書かなくてもいいようにワークシード関数があるんじゃないか
わざわざ手間かけてバグ作りたいようなマゾはコード書かないでくれマジで
0686デフォルトの名無しさん2014/06/12(木) 21:27:48.55ID:A1ckDykJ
ワークシード関数が何なのかわからないけどババァに使いこなせんのか、それは
0687デフォルトの名無しさん2014/06/12(木) 21:29:30.29ID:leNeVPHt
ババアなの?!
0688デフォルトの名無しさん2014/06/12(木) 21:30:43.58ID:paP2EzQv
>>684
僕は上から目線じゃないからいいんですよ。偉そうに語ってるくせにできないやつが滑稽なんですw
0689デフォルトの名無しさん2014/06/12(木) 21:31:25.43ID:FQgQ1zJa
ババアは熊ん子だけ使いこなしとけ
0690デフォルトの名無しさん2014/06/12(木) 21:31:59.17ID:leNeVPHt
>>688
ああそう、まあがんばってね
0691デフォルトの名無しさん2014/06/12(木) 21:32:31.74ID:A1ckDykJ
>>688
>偉そうに語ってるくせにできないやつ

すげぇ上からじゃん
0692デフォルトの名無しさん2014/06/12(木) 21:33:12.72ID:JGtl8L6J
すみません、ボタン一つで簡単にでるようにするにはかなり難しいんですね
プログラミングのこと良く知らないのに軽い気持ちで質問してすみませんでした
0693デフォルトの名無しさん2014/06/12(木) 21:35:50.99ID:paP2EzQv
>>691
できないくせに質問者に偉そうな態度とってるやつを嘲笑ってるだけですよw
僕はそうはなりたくないなあ。反面教師にさせていただきますw
0694デフォルトの名無しさん2014/06/12(木) 21:37:43.46ID:leNeVPHt
>>692
ババアでも40くらいまでで可愛ければコード組んじゃうかもしれない。
意外にストライクゾーン広いんだ。
0695デフォルトの名無しさん2014/06/12(木) 21:38:15.19ID:paP2EzQv
>>692
問題ないと思います。質問するのは自由ですし、僕もできれば協力したいですけど、
実力が及ばず…。
0696デフォルトの名無しさん2014/06/12(木) 21:38:20.26ID:A1ckDykJ
>>693
もうなってるから心配すんな
0697デフォルトの名無しさん2014/06/12(木) 21:39:25.92ID:JgOg9e9B
>>693
お前この程度で本当に出来ない奴いると思うの?自分が出来ないからそんな事言っちゃうんだろ
0698デフォルトの名無しさん2014/06/12(木) 21:42:27.75ID:paP2EzQv
>>697
できるんだったらとっくに作ってると思いますけど。
できると口で言うだけなら僕にもできますよw
でもそういう虚勢を張るのって人としてどうかと思うから、正直にできないって僕は言います。
できるんですね?
0699デフォルトの名無しさん2014/06/12(木) 21:45:29.20ID:FQgQ1zJa
口でできるんなら下もいいじゃん、気持ちいいよ?
0700デフォルトの名無しさん2014/06/12(木) 21:56:20.85ID:A1ckDykJ
解決方法を教えてください、という質問に対して必要な回答は解決方法であって解決そのものでは無いし
後出しで「実際に解決してください」と言われても自分でやれとしか
0701デフォルトの名無しさん2014/06/12(木) 21:59:13.12ID:JgOg9e9B
>>698
悪いが煽りは逆効果だ
これで答えたら他の奴がマネするからな
0702デフォルトの名無しさん2014/06/12(木) 21:59:30.00ID:paP2EzQv
>>700
あははw
0703デフォルトの名無しさん2014/06/12(木) 22:01:34.14ID:paP2EzQv
>>701
できないんですね。それじゃあ僕と同じですねw
正直にできないって言える分僕の方が大人です。
0704デフォルトの名無しさん2014/06/12(木) 22:10:30.70ID:yqko6Nwn
A.xlsを開いてB.xlsを呼び出し
B.xlsの値を参照した後B.xlsを閉じる際に

If Workbooks.Count = 2 Then ActiveWorkbook.Close

これで閉じてるのですが、こっちが普通ってやり方ありませんか?
上記のだとすぐ問題が起きそうで
0705デフォルトの名無しさん2014/06/12(木) 22:12:05.33ID:JGtl8L6J
日別の購入データの通し番号から、マスターを参照してジャンル分けして、ジャンルごとの合計金額を出したいです。

http://light.dotup.org/uploda/light.dotup.org28231.png

データはこのような画像の通りにシート3つに分かれて存在しています。
どのようなマクロを組めばいいかお教え願いたいです。
ジャンルごとに変数というものを持たないといけないのでしょうか?
実際は母が使うので、ボタン一つで出来るのだとありがたいのですが・・・
大変面倒な質問ですが、お願いします
0706デフォルトの名無しさん2014/06/12(木) 22:14:44.17ID:JGtl8L6J
> SQLを投げて、レコードセットに取得した値を他のシートに展開する
これどうやるんですか?実際に教えてください
0707デフォルトの名無しさん2014/06/12(木) 22:23:06.96ID:FQgQ1zJa
Try {
throw SQL
} Catch Values as RecordSet {
RecordSet.extract(Other.Shit)
}
0708デフォルトの名無しさん2014/06/12(木) 22:24:27.04ID:JGtl8L6J
>>707
このスレにまともにコード描ける人が居ないってのは良く分かりました
なんかわざと荒らしをして煽って邪魔する人も居るし
答え出るまでこのスレ居ますね
0709デフォルトの名無しさん2014/06/12(木) 22:26:34.93ID:JGtl8L6J
>>704
それが普通です
0710デフォルトの名無しさん2014/06/12(木) 22:26:53.60ID:A1ckDykJ
>>704
B.xlsを開いた直後にset BookB as ActiveWorkbook みたいな感じで
B.xlsを捕捉しておいて処理後にBookBをCloseするか

エクセルの仕様上、同名のファイルは開けないのでB.xlsのファイル名を保持しておいて
処理後に開いてるブックの中からB.xlsを見つけて閉じるか
0711デフォルトの名無しさん2014/06/12(木) 22:27:54.98ID:A1ckDykJ
Set BookB = ActiveWorkbook だった
0712デフォルトの名無しさん2014/06/12(木) 22:29:02.22ID:JGtl8L6J
>>711
日別の購入データの通し番号から、マスターを参照してジャンル分けして、ジャンルごとの合計金額を出したいです。

http://light.dotup.org/uploda/light.dotup.org28231.png

データはこのような画像の通りにシート3つに分かれて存在しています。
どのようなマクロを組めばいいかお教え願いたいです。
ジャンルごとに変数というものを持たないといけないのでしょうか?
実際は母が使うので、ボタン一つで出来るのだとありがたいのですが・・・
大変面倒な質問ですが、お願いします

コードを教えてくださいお願いします
正確なコードが出るまで居座ります
嘘の答えも言い続けます
0713デフォルトの名無しさん2014/06/12(木) 22:33:24.33ID:JgOg9e9B
>>709
お前は黙っとけw>>710が普通
0714デフォルトの名無しさん2014/06/12(木) 22:35:53.98ID:JGtl8L6J
頼むから教えてくれ本当に困ってるんだ
私が馬鹿な人間なのは分かっているし、これが自分のためのものなら諦めるけど
本当に困ってるんですお願いです
07157042014/06/12(木) 22:49:20.79ID:yqko6Nwn
ありがとうございます!
0716デフォルトの名無しさん2014/06/12(木) 22:50:33.31ID:JGtl8L6J
>>715
私の質問のコード教えてくれませんかお願いします
本当に困ってるんです助けると思ってお願いします
0717デフォルトの名無しさん2014/06/12(木) 22:54:21.41ID:FQgQ1zJa
いいかげんにしろババア人にもの頼むときはまずマンコぐらいさらせ
0718デフォルトの名無しさん2014/06/12(木) 22:58:24.36ID:leNeVPHt
>>706

Sub TotalAmount()
Dim dbCon As ADODB.Connection
Dim strsql As String
Dim dbRes As ADODB.Recordset
Dim Col As Long
Dim Row As Long
Set dbCon = New ADODB.Connection
With dbCon
.Provider = "Microsoft.Jet.OLEDB.4.0"
.Properties("Extended Properties") = "Excel 8.0"
.Open ThisWorkbook.FullName
End With
strsql = "SELECT B.ジャンル ,SUM(A.価格) AS 合計金額 FROM [Sheet1$] A INNER JOIN [Sheet2$] B ON A.通し番号 = B.通し番号 GROUP BY B.ジャンル"
Set dbRes = New ADODB.Recordset
dbRes.CursorLocation = adUseClient
dbRes.Open strsql, dbCon, adOpenDynamic, adLockOptimistic, adCmdText

つづく
0719デフォルトの名無しさん2014/06/12(木) 23:00:50.52ID:leNeVPHt
つづき

With Worksheets("sheet3")
.Cells.ClearContents
For Col = 1 To dbRes.Fields.Count
.Cells(1, Col).Value = dbRes.Fields(Col - 1).Name
Next Col
Row = 1
Do Until dbRes.EOF
Row = Row + 1
For Col = 1 To dbRes.Fields.Count
.Cells(Row, Col).Value = dbRes.Fields(Col - 1).Value
Next Col
dbRes.MoveNext
Loop
End With
dbRes.Close: Set dbRes = Nothing
dbCon.Close: Set dbCon = Nothing
End Sub

こんな感じ。

シート1,2に設定しとけばシート3に書き出すよ。
ただし、Microsoft ActiveX Data Objects 2.8 Libraryの参照設定をきっとくこと。
0720デフォルトの名無しさん2014/06/12(木) 23:02:10.06ID:JgOg9e9B
>>716
VLOOKUPとSUMIFで出来るからまじで
1.ジャンル分けしたいデータ4列目にジャンル列追加
2.ジャンル列にVLOOKUPでジャンルを設定
3.合計金額列にSUMIFでジャンル毎の集計値を設定
0721デフォルトの名無しさん2014/06/12(木) 23:07:09.27ID:JGtl8L6J
>>719
ユーザー定義型は定義されていませんってでます

> Microsoft ActiveX Data Objects 2.8 Libraryの参照設定をきっとくこと
これはどうしたらできます?
調べても出てきません
だまされてますか?
0722デフォルトの名無しさん2014/06/12(木) 23:10:35.81ID:leNeVPHt
>>721
おんぶにだっこだなぁ。
VBEでツール→参照設定でそれを選んでOK押せば参照してくれるから。
0723デフォルトの名無しさん2014/06/12(木) 23:13:09.28ID:JGtl8L6J
>>722
それにはチェック入ってませんでした
調べたらDAOなんたらってのにチェック入れたらいけるって書いてましたが
チェックいれたらDLLエラーってでました。
もっと簡単に出来る方法ないんでしょうか
もうしにたくなってきました
0724デフォルトの名無しさん2014/06/12(木) 23:19:00.19ID:leNeVPHt
>>723
いやだからチェック入れないと。
今回使っているのはDAOじゃなくてADOだから。
0725デフォルトの名無しさん2014/06/12(木) 23:32:14.62ID:leNeVPHt
さて、コードも書いたことだし、
とりあえずID:paP2EzQvは死んでくれないかな。
0726デフォルトの名無しさん2014/06/12(木) 23:57:38.17ID:DSeU12c2
>>710-711

A.xlsにあるマクロでB.xlsを開くんだったら
開いてからアクティブなブックをオブジェクト変数にセットするより
開くときにオブジェクト変数に直接突っ込んだ方が早くない?

Dim bookB As Workbook
Set bookB = Workbooks.Open(B.xls)

とかやっとけばいっぺんで終わる
0727デフォルトの名無しさん2014/06/13(金) 00:05:35.25ID:3uExzG0V
>>726
うん。そう出来るんなら
外部からアクティブなブック変えられても安全だね。
0728デフォルトの名無しさん2014/06/13(金) 01:02:52.06ID:mgi5uvuR
vbaと直接的に関係あるかは微妙ですが、Excelマクロブックがたまに壊れてしまいます。開いてマクロを起動するとエラーを起こして強制終了になるのです。
たいていその時は他のいくつかのマクロにまで同様の被害を出し、困っています。

今のところは、作業ブックとマクロブックは必ず分けて、さらにメモ帳でマクロのプログラムを保存しておいて、もし壊れたらマクロブックは捨てて新しく作り直して対処しています。

ただ、作業ブックで直接マクロを呼び出せれば非常に便利なのでそれを検討しています。

質問は二つです
1)壊れる理由はなんなのでしょうか?
2)普通の作業ブックにマクロを用意すると、上記のように壊れたとき作業ブックごと壊れそうで怖いです。
壊れると思うとためらってしまいます。何か良い対処法はありませんか?
0729デフォルトの名無しさん2014/06/13(金) 02:05:30.86ID:/KfsTB1C
>>728
マクロが壊れるってどういうこと?VBAのソースが書き換わってるの?
別のパソコンでは試した?
0730デフォルトの名無しさん2014/06/13(金) 02:25:20.51ID:QETwEf+A
>>728
自分自身マクロが壊れた経験は無いし、知人からも聞いたこと無いけど、
そういう理由ではなくマクロのブックとデータのブックは大抵別にしてるよ。

俺の仕事だと大抵の場合年度ごとにデータは変わるから、
マクロ入りのブックを毎年更新するのは面倒くさい。
マクロを別にしとけばデータブックだけ変えて作業できる。
もちろん、年度の指定はマクロで出来るように作ってある。

まぁ、一回コッキリの作業だったら
マクロ入りのブックにデータも入れ込むのもアリだと思うけど、
そうでなければ別体にしといたほうが作業性は上がるよ。
■ このスレッドは過去ログ倉庫に格納されています