5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

Excel VBA質問スレ Part7

1 :デフォルトの名無しさん:2008/06/04(水) 22:56:59
すまんが2の人テンプレやって

ExcelのVBAに関する質問スレです

質問前に 【 >>2-3 】 あたりを良く読むこと

前スレ http://pc11.2ch.net/test/read.cgi/tech/1205231499/l50


★1 質問テンプレ(雛形)は用意しませんが、OSとExcelのバージョンは必ず書きましょう。

★2 ExcelのVBA以外の部分に関する質問はNGです。
   但し、VBA無しでも出来ることだが、あえてVBAでやりたいって物に関してはOK。

★3 ExcelのVBE(Visual Basic Editor)を使うとしても、VBAの分野以外に関してはスレ違いです。
   
 VBAとは、『Visual Basic for Application』の略で
  Application
  ├Workbooks
  |└Workbook
  |  ├Worksheets
  |  |└Worksheet
 というApplication以下のオブジェクトを、VB言語で操作するものを指します。 
 例えExcel付属のVBE(Visual Basic Editor)を利用しようとも、このApplication以下のブックやシート、
 セルやオブジェクト等を操作するもの以外はVBA分野の話ではないので、ここでは聞かないでください。

★4 とりあえず、Excelのインスタンスを作らずにVB6で出来ることは全てスレ違いだと思ってください。

★5 レベルはどうあれ、ここはプログラマ用の板スレです。プログラマとは、自分でプログラムを組み
   コードを書く人の事なので、自分でやるきは全く無く、丸投げしようって人はお断りです。
   ヒントを貰えばあとは自力でなんとかしますって人のみどうぞ。

2 :デフォルトの名無しさん:2008/06/04(水) 22:57:51
過去スレ
01 http://pc11.2ch.net/test/read.cgi/tech/1054356121/
02 http://pc11.2ch.net/test/read.cgi/tech/1168308855/
03 http://pc11.2ch.net/test/read.cgi/tech/1180192018/
04 http://pc11.2ch.net/test/read.cgi/tech/1189814602/
05 http://pc11.2ch.net/test/read.cgi/tech/1197448064/

3 :デフォルトの名無しさん:2008/06/04(水) 23:00:00
早速ですが
エクセルでVBAの
プログラムで001.csv-999.csvまでのCSVファイルを順に読んでアクセスDBに
入れたいのだが
まず変数 csvnameでCSVファイルを読み込むにはどうすればいいのですか?


4 :デフォルトの名無しさん:2008/06/05(木) 00:35:48
Accessでやれ。

はい、次。

5 :デフォルトの名無しさん:2008/06/05(木) 11:00:07
どうやったら彼女が出来ますか?

6 :デフォルトの名無しさん:2008/06/05(木) 15:17:33
>>5
VBAを習得してからの私はそれはもうモテモテです

7 :デフォルトの名無しさん:2008/06/05(木) 15:39:54
>>4
エクセルでのやり方が解らないからって代替を強制すんな無能

8 :デフォルトの名無しさん:2008/06/05(木) 17:44:40
>>7
>>4ではないが、この要件にExcelをかます意味ある?
ExcelVBAが得意な人がわざわざExcelVBAでやるならわかるけど、
ExcelVBAが使えないならAccessVBAなりVBなりの質問掲示板で質問するべきでは?

9 :デフォルトの名無しさん:2008/06/05(木) 18:16:24
>>8
バカじゃねえのか?
エクセルVBAでって指定してんだから、意味なんかお前が勝手に判断すんなボケ

10 :デフォルトの名無しさん:2008/06/05(木) 18:22:48
アクセスって立ち上げるの面倒くさい。

11 :デフォルトの名無しさん:2008/06/05(木) 18:25:03
>>8
まぁまぁ、そんなイライラせずに仲良くやろうよ(^^
そんで、なんでわざわざExcelVBAを使いたいんだーい?

12 :デフォルトの名無しさん:2008/06/05(木) 18:57:26
全スレ>>998

ありがとうございました。 パターン 「.*?」 の正規表現ですっきりできました。

13 :3:2008/06/05(木) 19:05:53
自己解決しました。

14 :デフォルトの名無しさん:2008/06/05(木) 19:23:04
チェックボックスをONにしたらOffset(0,10)に"1"を入れる方法教えて下さい

15 :14:2008/06/05(木) 19:46:24
できたからいいわw

16 :デフォルトの名無しさん:2008/06/05(木) 20:20:32
ExcelVBAで、g解決しました。

17 :デフォルトの名無しさん:2008/06/06(金) 02:16:52
>>11
あるよ。
以上。
はい、次。

18 :デフォルトの名無しさん:2008/06/06(金) 20:37:48
教えてください・・
エクセルVBAで質問です

二次元配列で例えば、ab(a、1)=10だとして
変数wk-hensuに、1が入っていたとします

wk-hensuの1を使って二次元配列の10の値を
取得したいのですが、どうすればよろしいですか?

19 :デフォルトの名無しさん:2008/06/06(金) 20:46:47
さっぱり意味がわからない

20 :デフォルトの名無しさん:2008/06/06(金) 20:57:35
>>18
ab(a、wk-hensu)=10
こうですか!?わかりません!

21 :デフォルトの名無しさん:2008/06/06(金) 22:23:45
Dim STMM As Worksheets
Dim STEE As Worksheets

Set STEE = Sheets("平面" & CStr(a%))
Set STMM = Sheets("データ" & a%)

オブジェクトがはいらん。なんで?
なにがいけないのか?



22 :デフォルトの名無しさん:2008/06/06(金) 22:26:43
>>18
>>20
これが正解だと思われ

23 :デフォルトの名無しさん:2008/06/06(金) 22:32:51
>>22
それだと取得できないぞ。

24 :デフォルトの名無しさん:2008/06/06(金) 22:35:11
>>23
そうだね
ab(a、wk-hensu)=10 じゃなくて
新しい変数=ab(a、wk-hensu) だね

25 :デフォルトの名無しさん:2008/06/07(土) 00:02:54
>>21
>なにがいけないのか?

変数の型

26 :デフォルトの名無しさん:2008/06/07(土) 08:25:59
コレクションがよくわからん。
最近、VBも使うようにしてるので、オブジェクトSetも努力しているんだが、

たとえばこの>>21のケースのように、

sheetsを特定して格納したい、workbookを特定して格納したい、
ってときはどんなオブジェクトを宣言すればよろしい?

rangeオブジェクトのときは、cell範囲指定すれば入ることはわかるがどーちがうのかな・・
頼むヒントを


27 :デフォルトの名無しさん:2008/06/07(土) 08:56:31
いや、ヘルプ見ろよ

28 :デフォルトの名無しさん:2008/06/07(土) 10:12:07
折れにはよくはわからんが、
Dim STMM As Worksheet
Dim STEE As Worksheet
で、だめかな?


29 :28:2008/06/07(土) 10:16:26
worksheetsとsを付けたから跳ねられていると推測しただけ。


30 :25:2008/06/07(土) 13:41:08
>>26
worksheets型はワークシートコレクションオブジェクト
使い方は、
dim ws as worksheets
set ws= thisworkbook.worksheets
ってカンジ
まず、worksheets型変数の使い道はない

worksheet型はワークシートオブジェクト
使い方は、
dim ws as worksheet
set ws = thisworkbook.worksheets("Sheet1")
ってカンジ
普通はこっち

31 :デフォルトの名無しさん:2008/06/07(土) 17:11:46
セルのA1からA10と、B1からB10に数値が入っています
これをgolf(9,9)配列に入れたい場合はどうすればいいですか?
初心者なのでよくわかりません。お願いします


32 :デフォルトの名無しさん:2008/06/07(土) 17:43:44
>>31
>golf(9,9)

10×10=100要素あるけど、どこに入れたいの?

dim golf() as variant
golf()=range("A1","B10").value
って方法もあるよ


33 :デフォルトの名無しさん:2008/06/07(土) 17:57:57
>>32
ありがとうございます!
できました

もうひとついいですか?
先ほどの続きで

エクセルをイメージしています
  A B C
1 0 0 10
2 0 1 11
3 0 2 12
4 0 3 13
5 0 4 14
6 0 5 15
7 0 6 16
8 0 7 17
9 0 8 18

golf(0,0)=10
golf(0,1)=11
  ・
  ・ 
とプログラムで打つのが面倒なので、簡単に配列にセル値(ここでいうC列)を
代入できることは可能ですか?

34 :デフォルトの名無しさん:2008/06/07(土) 19:06:54
>>33
dim i as long

for i=0 to 9
  golf(0,i)=cells(i+1,"C").value
next i

35 :デフォルトの名無しさん:2008/06/07(土) 19:35:17
>>34
インデックスが有効範囲にありませんとでますが
どうしたらいいでしょうか?

36 :デフォルトの名無しさん:2008/06/07(土) 19:50:11
golf(0,i)=cells(i+1,3).value かな

37 :デフォルトの名無しさん:2008/06/07(土) 19:53:26
>>35
golfを適切に宣言してますか?

>>36
??

38 :デフォルトの名無しさん:2008/06/07(土) 19:54:38
"C"でも行けるよ
golfをちゃんとdimしてないんだろ

39 :38:2008/06/07(土) 19:55:13
おっとすまんかぶった

40 :35:2008/06/07(土) 20:00:22
golfはdim golf() as variantと宣言しています・・・

41 :デフォルトの名無しさん:2008/06/07(土) 20:27:07
うん、それじゃダメだね

42 :デフォルトの名無しさん:2008/06/07(土) 20:27:44
>>40
この場合は dim golf(9,9) で宣言する

43 :35:2008/06/07(土) 20:36:53
できました!!ありがとうございます!

44 :26:2008/06/07(土) 21:28:31
おお、ありがとう。
なるほどWorksheetで宣言するのか。入った入った。これでキレイなコーディングに一歩近づいた。

さっき超アツイ事をしった。

Inputbox関数
Application.Inputboxメソッド

後者のメソッドはTypeが指定できるぜ!

45 :デフォルトの名無しさん:2008/06/08(日) 09:54:38
ブックAとブックBが開かれているときに、
ブックAからブックBのmacro1()を実行したい場合

call ブックA.xls!macro1
でいいのでしょうか。


46 :デフォルトの名無しさん:2008/06/08(日) 10:08:31
やってみれば済む話だろう

47 :45:2008/06/08(日) 11:31:11
それが、最近も出来ていたと思うんですが、今回、コンパイルエラーで跳ねられた。
!の所をさして、修正候補 又は(  という具合で。
どうも、文法的に勘違いをしていたようなので、訊いてみました。
現実には、.runで解決済みですが。


48 :デフォルトの名無しさん:2008/06/08(日) 13:19:15
ならば>>45の回答は「だめ」

49 :デフォルトの名無しさん:2008/06/08(日) 22:06:40
超くだらねーことかもしれんが、適当な変数宣言の一般的な名称ってどんなもんがあるかね?

@たとえば、インテジャーなら?
Aロングなら何使う?
Bレンジなら?
Cワークシートなら?
Dブーリアンなら?


俺は考えるのが面倒だからすぐバカみたいな変数宣言するので
とても人に見せれん。

TAROU
UNKO
MANKO
DEVILMAN
RAOU
KENSIROU
とかよ。

数年たっても自分のクセなんで、クチャクチャな宣言でも自分はわかるんだよね、これが。

50 :デフォルトの名無しさん:2008/06/09(月) 00:00:34
>>49
型はさておき、その変数が指すものを表現する名前がいいんじゃないか。
太郎くんのことを表現したいのならTAROUでも差し支えないと思う。

51 :デフォルトの名無しさん:2008/06/09(月) 00:14:40
個人オンリーのものなら好き勝手に
会社とかで、んな変数名にしていやがったら、張り倒すけどな。

52 :デフォルトの名無しさん:2008/06/09(月) 06:57:39
一般的な変数名なんてループに使うi、j、kくらいだべ

53 :デフォルトの名無しさん:2008/06/09(月) 13:21:18
TZEF2101
CMED9301

54 :デフォルトの名無しさん:2008/06/09(月) 23:08:23
>>51
当然会社のやつ。俺以外はVBAの変数を理解しているやつがいないからやっちまった。

>>52
ループでそれらの変数は使うのかな?
俺の場合、ループの時はインテジャなら大体a%,b%とかで適当に回す。
なんかだれがみてもわかるような変数や構文のコツがあるかな。

たとえばプライベートサブやらを Callするときは必ず全角文字を使うとか、コメントをつけまくるってクセは付けてる。

55 :デフォルトの名無しさん:2008/06/09(月) 23:14:34
ループは俺もi、j、k、l、Index、この辺だな
てか会社でそんなあほなことは絶対にやめておけ
どんな業種か知らんがたいてい知らん振りしてるだけでけっこう知ってる人はいるもんだ

56 :デフォルトの名無しさん:2008/06/09(月) 23:15:10
VBAをかなり理解してるやつ(ステートメント、条件式、階層の完全理解くらい)とか身近な人間でいる?
会社とか大きな組織とか行くと多少のVBAプログラムされているものは見るが、
バグの固まりみたいなもので、共有して使っているのが不思議なものしかみたことない。
手順書すらなくて、非常に困る。

俺的にはこんなものはプログラムではない、と思うんだが、そんなこと偉そうに言える立場ではないので
我慢してヒマを見てはコードを改造しているが、似たような境遇の人はいないかい?

57 :デフォルトの名無しさん:2008/06/09(月) 23:21:20
>>55
以後気をつけます。 しっかし、変数名考えるのめんどくせぇーなー。
ところで、自分はあんまりやったことないんだが、↓

dim I(100) as Long

↑これってインデックス付きの変数Iを100個宣言してるんだよね?

で、代入するときは
I(1)=1
I(2)=5 とかで。

この番号ふった大量の変数Iを活用するには当然ループさせるときに効果を発揮すると思うんだが、
俺を相手してくれる暇人が居るならば、具体的になんか適当なコードを書いてみせてくれんかな?



58 :デフォルトの名無しさん:2008/06/09(月) 23:28:11
Dim i(1 to 10) As Integer とか俺はけっこう使うぞ

59 :デフォルトの名無しさん:2008/06/10(火) 00:55:39
配列を効率的に使いこなせるようになったら脱VBA初心者

と、個人的に思ってる
やっとこのレベルあたりで独力で多少役に立つモノ作れるようになるんじゃない?

60 :デフォルトの名無しさん:2008/06/10(火) 02:39:35
マスタのシートの表で0という値が入力された場合に
特定のシートを非表示にさせるには
どのようにすればよろしいのでしょうか?

61 :デフォルトの名無しさん:2008/06/10(火) 02:50:43
>>60
Private Sub Worksheet_Change(ByVal Target As Range)

  If Target.Address(False, False) = "A1" Then
    Select Case Target.Value
      Case 0
        Sheet2.Visible = xlSheetHidden
      Case 1
        Sheet2.Visible = xlSheetVisible
    End Select
  End If

End Sub

62 :p2134-ipbf1308souka.saitama.ocn.ne.jp:2008/06/10(火) 10:29:29


63 :デフォルトの名無しさん:2008/06/10(火) 11:36:10
創価ktkr

64 :デフォルトの名無しさん:2008/06/10(火) 18:00:38
>>49はスゲーと思う。
俺なんて適当でも、ハンガリアン表記?ってやつの呪縛から逃れられない。
かといって、確実に誰でもわかるかっていったらどうなのか微妙な中途半端さ
何にもないところからデビルマンとかケンシロウが出てくるお前ってスゲーな。


65 :デフォルトの名無しさん:2008/06/10(火) 20:51:58
RPGのキャラの名前はデフォのままってタイプだな>>64

66 :デフォルトの名無しさん:2008/06/10(火) 21:53:09
変数名とか普通にi、j、k…で十分じゃね?

67 :デフォルトの名無しさん:2008/06/10(火) 22:14:36
regexpについて質問させてください。
動作的な問題では無く、何とか動かしてはいるのですが、気になることがあります。

executeメソッドは、マッチしたものを”コレクション”に格納して行くと説明文にあります。

通常のコレクションの場合、デフォルトだと MyCollection(1) から格納されて行くと記憶しておりますが、
regexpのexecuteで格納されて行くコレクションには、MyMatch(0) から格納されております。

漠然と、配列は (0) から、コレクションは (1) から、と覚えていたのですが、
regexpの”コレクション”は、VBAで定義する通常のコレクションとは異なる物なのでしょうか。

また、(0)から格納されているので、実は配列なのかと思い、joinを試したのですがダメでした。
そこで for でまわして、 MyArray(i) = MyMatch(i) と、一度配列に再格納してからjoinを行っております。
この方法について、何か最適化の手立てはありますでしょうか。

なにとぞご教授をよろしくお願いします。

68 :デフォルトの名無しさん:2008/06/11(水) 00:02:07
>>67
CollectionとMatchCollectionは別物
名前が似てるからって勝手に同一視してはいけない

ていうか、DictionaryオブジェクトみたいにKeysとかItemsとかって
プロパティがあればJoinも可能だけど、MatchCollectionには
ItemとCountしかプロパティが無いんだからどう考えても無理

>MyArray(i) = MyMatch(i) と、一度配列に再格納してからjoin

どうせループするんだから配列に格納してからJoinなんてせず、
ループしながら連結すればいい

69 :デフォルトの名無しさん:2008/06/11(水) 07:45:48
Dateadd使っての日付計算で困っています
シート:
A列には”注射”という文字を入れるようにします。
B列には1月1日から12月31日まで入っています。
C列はB列の90日後を入れるようにします。
D列はC列の3日前を入れます。・・・としたいのですがその3日の間A列に”注射”が入っていたらその日を入れずに3日前にしたいのです。 稼働日みたいな感じでしょうか・・・・どうしたらよいでしょうか?お願いします。
例としてB列の「1月1日」の90日後はC列「3月31日」でD列は通常「3月28日」が入っていますがB列「3月30日」の左のA列に”注射”があったらそこを無視して「3月27日」と入れたいのです。
DateaddじゃなくてDo
While〜でC列の日付より3日前にした方がいいのでしょうか…そしてA列に注射の文字列がない場合?すみません…どうしていいのかちんぷんかんぷんです…Sub count()
Dim i As Long
Dim lastrow As Long
lastrow = Range("B1").End(xlDown).Row
For i = 1 To lastrow
Cells(i, 3).Value = DateAdd("d", 90, Cells(i, 2).Value)
Next
For i = 1 To lastrow
Cells(i, 4).Value = DateAdd("d", -3, Cells(i, 3).Value)
Next
End Sub

説明が下手なのでもしよかったら実際作ったものを見ていただいた方が分かるかもしれません。

http://briefcase.yahoo.co.jp/bc/robert_kubica_bmw/vwp2?.tok=bcf8oGbB4FXgt88k&.dir=/&.dnm=1count.xls&.src=bc

70 :デフォルトの名無しさん:2008/06/11(水) 13:35:29
>69 こういうことですか?
   A   B   C   D
−−−−−−−−−−−−−−−−−−−−−−−−−
1 空白 2008/1/1 =B1+90 =IF(A91="注射",C1-4,C1-3)
−−−−−−−−−−−−−−−−−−−−−−−−−
2 空白 =B1+1   =B1+90 =IF(A92="注射",C2-4,C2-3)
−−−−−−−−−−−−−−−−−−−−−−−−−
3 空白 =B2+1   =B1+90 =IF(A93="注射",C3-4,C3-3)
−−−−−−−−−−−−−−−−−−−−−−−−−

−−−−−−−−−−−−−−−−−−−−−−−−−
90 空白 =B89+1  =B90+90 =IF(A180="注射",C90-4,C90-3)
−−−−−−−−−−−−−−−−−−−−−−−−−
91 注射 =B90+1  =B91+90 =IF(A181="注射",C91-4,C90-3)
−−−−−−−−−−−−−−−−−−−−−−−−−
単に90日後の行のA列の値で判断できるのであれば、IF関数でいいけど、
「その3日の間A列に”注射”が入っていたらその日を入れずに」ということ
であれば、88日後の行、89日後の行もA列に"注射"があるかどうかを
調べる必要がありますね。作業列を使えばいいようです。  次?に続きます。

71 :デフォルトの名無しさん:2008/06/11(水) 13:52:02
88〜90日後の3日間の「注射」の有無をみるのであれば作業用の3列を組み合わせる方法がいいかと思います。

   A   B     C     D        E          F         G       
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
1 空白 2008/1/1  =B1+90  =C1-SUM(3,E1:G1) =IF(A89="注射",1,0) =IF(A90="注射",1,0) =IF(A91="注射",1,0)
−−−−−−−−−−−−−−−−−−−−−−−−−

−−−−−−−−−−−−−−−−−−−−−−−−−
89 注射 =B88+1  =B89+90
−−−−−−−−−−−−−−−−−−−−−−−−−
90 空白 =B89+1  =B90+90
−−−−−−−−−−−−−−−−−−−−−−−−−
91 注射 =B90+1  =B91+90
−−−−−−−−−−−−−−−−−−−−−−−−−
上記の例では、A89とA91が「注射」なので、E1とG1が1、F1は0なので、D1の値は3月26日に
なります。


72 :デフォルトの名無しさん:2008/06/11(水) 14:50:38
>>70
VBA質問スレですが…

73 :70,71:2008/06/11(水) 15:07:32
>72
そうでしたね。しかも71まで書いちゃって。おはずかしい。
ではVBAで
D列の値を設定する部分をこうしたらどうでしょう。
ループ用変数 j as long を追加したうえで、69のソースの下から4行目から3行分を
  For i = 1 To lastrow
    Cells(i, 4).Value = DateAdd("d", -3, Cells(i, 3).Value)
追加  For j = 88 to 90
追加    if Cells(i + j, 1).value = "注射" Then
追加      Cells(i, 4).Value = Cells(i, 4).Value - 1
追加    end If
追加  Next j
  Next
調査範囲の3日間について、注射という文字があれば各1日ずつ前の日付になります。

74 :67:2008/06/11(水) 21:42:37
>>68
レスありがとうございました。
お教えの通り、

cells(i,2).value = cells(i,2).value & vblf & myMatch(j)

のような形で連結させる事ができました。
本当にありがとうございます。

75 :デフォルトの名無しさん:2008/06/11(水) 23:27:58
>>68
まさかループしながら&演算子で連結しろって言ってないよな?

76 :デフォルトの名無しさん:2008/06/11(水) 23:31:12
>>75
勿論そのつもり
何でまさかなのかわからん

77 :デフォルトの名無しさん:2008/06/12(木) 00:39:15
OSはXPでエクセル2003です。
二つの正の整数の公約数を全て求め、
セルに一つずつ表示させるようなプログラムをVBAで作りたいのですが、

a = InputBox("正の整数を入力してください。")
If a < 0 Then
MsgBox ("正の整数を入力してください。")
End If
Cells(1, 1).Value = a
b = InputBox("正の整数を入力してください。")
If b < 0 Then
MsgBox ("正の整数を入力してください。")
End If
Cells(2, 1).Value = b

If a < b Then
a = c
Else
b = c
End If

For e = 2 To c Step 1

f = a Mod e
Cells(5, c).Value = f
g = b Mod e
Cells(6, c).Value = g

Next
End Sub
ここまで書いて挫折しそうです。どなたかアドバイスをいただけませんか?

78 :デフォルトの名無しさん:2008/06/12(木) 01:07:46
>>77
間違ってたらすまん

Dim a As Long, b As Long, c As Long, e As Long, f As Long
On Error Resume Next
Do
  a = Application.InputBox("正の整数を入力してください。", , , , , , 1)
  If a = -1 Then Exit Sub 'ループ脱出用 -1を入力したら終了
Loop Until a > 0
Do
  b = Application.InputBox("正の整数を入力してください。", , , , , , 1)
  If b = -1 Then Exit Sub
Loop Until b > 0
On Error GoTo 0
If a < b Then
  c = a
Else
  c = b
End If
Range("A1").Value = a
Range("A2").Value = b
f = 1
For e = 2 To c
  If a Mod e = 0 Then
    If b Mod e = 0 Then
      Cells(f, "B").Value = e
      f = f + 1
    End If
  End If
Next

79 :デフォルトの名無しさん:2008/06/12(木) 01:08:04
ユーザフォームを表示したいので、以下のようにやったのですが、エラーになります。
Private Sub XXX()
  Dim DlgInst As UserForm1

  'インスタンス作成
  Set DlgInst = UserForm1

  '表示する。
  DlgInst.Show

  Unload DlgInst
End Sub

実行時エラー'424'
オブジェクトが必要です。


自分の理解では
CUserForm1 * pDlg;
pDlg = new CUserForm1;
pDlg->Show();
pDlg->SendMessage(WM_CLOSE);

というつもりで書いたのですが。。
VBAの場合、どうやってユーザフォームを表示するのが正しいのですか??


80 :デフォルトの名無しさん:2008/06/12(木) 01:10:55
>>78さんありがとうございます。
参考にさせていただきます。

81 :デフォルトの名無しさん:2008/06/12(木) 01:12:59
>>79
VBAではダイレクトに UserForm1.Show
Unload は UserForm1 のコマンドボタンのクリックイベントなどに書く
その場合は一般的に、 Unload UserForm1 では無く、 Unload Me と書く

82 :デフォルトの名無しさん:2008/06/12(木) 01:16:29
>>69です
どうも要件が私自身混乱してしまって・・・C列に入る日付とかは度外視してください。
とにかく入っている日付を3日前倒します。
条件はA列を参照しもし文字が入っていなければ稼働日とみなす 文字があればそういった日を抜かし
3日前倒す としたいんですがうまくいきません 別サンプル作ってみたけど・・・ダメでした

Sub count()
Dim i As Long
Dim j As Long
Dim lastrow As Long
Dim ctr As Long
lastrow = Range("D12").End(xlDown).Row
For i = 12 To lastrow
Cells(i, .Value = DateAdd("d", 30, Cells(i, 4).Value)
Next
For i = 12 To lastrow
j = lastrow
Do While Cells(i, .Value <> Cells(j, 4).Value
j = j - 1
If j = 0 Then Exit Sub
Loop
Do While ctr < 4
If InStr(1, Cells(j - 1, 7).Value, "病院", 1) = 0 Then
ctr = ctr + 1
End If
j = j - 1
Loop
Cells(i, 11).Value = Sheets("Sheet1").Cells(j, 4).Value
ctr = 0
Next
End Sub

83 :デフォルトの名無しさん:2008/06/12(木) 01:22:50
>>82
>Cells(i, .Value
コレは何を意味してんの?

84 :デフォルトの名無しさん:2008/06/12(木) 01:22:54
>>81
ありがとうございます。

UserForm1は型であるという私の考え方が間違っていて、
UserForm1は型であり、オブジェクトのインスタンスであると考えるのがVBAなのでしょうか?
(どうせシングルスレッドだし、複数のインスタンスは作れないから?)

うーーーーん
VBAムズカシイ



85 :84:2008/06/12(木) 01:27:10
とおもったけどやっぱり同じエラーが。

よく見たらUserForm1.Initializeで変な記述してたのが原因でした。



86 :デフォルトの名無しさん:2008/06/12(木) 01:31:13
>>84
いや、VBAのUserFormは特別扱いだと思う
難しく考えると腹立つと思うよ
インスタンスという考え自体を意識しないでいいように設計されているんだと思う
VBA使いの98%(単なるオレの偏見)はインスタンスが何かも理解してない上に
インスタンスという言葉さえ知らないと思う
New すれば複数のインスタンスも作れるんじゃないかな?(未確認)

あくまでも、個人的な見解です

87 :デフォルトの名無しさん:2008/06/12(木) 01:35:50
>>85
VBEの ツール - オプション - 全般 - エラートラップ を クラスモジュールで中断
にチェックすると幸せになれるよ

88 :デフォルトの名無しさん:2008/06/12(木) 02:06:33
>>86
なるほど。わかりました!深く考えないことにします

>>87
早速やってみます。ありがとうございました

89 :デフォルトの名無しさん:2008/06/12(木) 07:08:00
>>82です
なんかコピペしたら消えてました・・・
>Cells(i, 8).Value です

90 :70,71,73:2008/06/12(木) 07:51:25
要件をはっきりさせましょう。
A列:通常は空白であるが、「注射」などの文字(数字も?)が入ることがある
   →何かはいっていた場合に「別の行の」D列に影響する
B列:連続した日付が入る(仮定として、B2セルに2008/1/1から366日分入っているものとする。)
C列:B列の90日後の日付が入る、ということでしたが、
   「C列の日付は度外視してください」とは、ここはD列の日付設定に関係しないということですか?
D列:通常ならばB列の87日後の日付が入るけど、

   B列の90行下方のA列が空白でないとき
条件 B列の88〜90行下の3行のA列のうちひとつでも空白でないとき
   B列の88〜90行下の3行のA列のうち空白でないセルの数だけ

処理 通常のD列の日付を前倒しする。

条件は3通りのうちどれですか? 上の要件になにか誤りがありますか?

91 :デフォルトの名無しさん:2008/06/12(木) 12:16:59
要件がかなり自分でもわからなくなってしまったのでもっと単純にしてみました。文章下手ですみませんが分かりやすくなりましたでしょうか?
VBAで*稼働日後の日付を出すとする。

A列には日付2008/1/1〜2009/3/31まで入っています。
B列には『休』とお休みに該当した日をいれます。(土日とは限らない)
例として1月1日(A1セル)が休みとしたらB1セルに『休』と入れお休み表にします。
C列には適当な日を手入力します。(規則性は全く無し)
D列はC列の3稼働日後を入れたいです。
AやB列からどうスキャンし3稼働日後を出したらよいのか…ちなみにアドイン関数は無いので使えません…よろしくお願いいたします。

92 :デフォルトの名無しさん:2008/06/12(木) 12:24:29
稼働日に連番を振るのがいちばん簡単だな

93 :デフォルトの名無しさん:2008/06/12(木) 12:32:15
回答ありがとうございます。
すみません。連番をふるとはどういうことでしょうか?初心者なので検討がつきません…

94 :デフォルトの名無しさん:2008/06/12(木) 12:41:04
つまりだな
日付 休日 連番
4/1      1
4/2      2
4/3 休
4/4      3
4/5      4

こんな感じ。4/1の3稼働日後は1+3=4だから連番が4の4/5になる

95 :デフォルトの名無しさん:2008/06/12(木) 15:01:55
印刷しようとする時にそのシートに"菓子"という言葉が無かったら印刷せず、
msgboxにて"菓子がありません"と表示するにはどうすれば良いんだよ、おしえろマクロヲタども

96 :70,71,73,90:2008/06/12(木) 18:00:46
>91
70,71,73,90です。最初(69番の書き込み)から90日後云々が消えちゃいましたが・・・
それから3営業日「前」の日付を求めたい、とあったのが今度は3営業日「後」の日付を
求めるんですか?
では、A列にカレンダー(1月1日〜12月31日)、B列に何かデータがあれば休みという前提で、
C1セルに日付を入力したら3営業日「後」の日付を求めるということで考えてみます。
C1セルの日付がカレンダーの何行目になるのかは、
Cells("C1").Value - Cells("A1").Value + 1 で求められます。A1セルを1/1としてます。
単純に3日後であれば3行下のA列の値でいいんですが、B列に何かあったらさらに1行下となるので、
ループを利用します。
Dim Tate As Long, i As Long
Sub D_day()
  Tate = DateDiff("d", Cells(1, 1).Value, Cells(1, 3).Value) + 1
  i = 0
  Do
    Tate = Tate + 1
    If Cells(Tate, 2).Value = "" Then 営業日だけ
      i = i + 1           カウントアップ
    End If
  Loop Until (i > 2)           3営業日になったらループ脱出
  Cells(1, 4).Value = Cells(Tate, 1).Value 
End Sub
これでどうでしょうか?

97 :70,71,73,90:2008/06/12(木) 18:11:56
96の続き
求める日付はD1セルに出力するようにしてますが、69の書き込みからいくと
基準日はC1のような固定ではないのかな?
何をしたいのかがイマイチよくわからない。


98 :デフォルトの名無しさん:2008/06/12(木) 18:50:30
なんつーか・・・


いい加減にしろ

99 :デフォルトの名無しさん:2008/06/12(木) 19:20:34
すいません95ですがホント教えてくれ

100 :デフォルトの名無しさん:2008/06/12(木) 19:28:58
>>99
                | ̄``''- 、
                |      `゙''ー- 、  ________
                |    ,. -‐ ''´ ̄ ̄`ヽ、_        /
                |, - '´ ̄              `ヽ、     /
              /               `ヽ、ヽ   /
             _/                    ヽヽ/
           / / /   /  /  /            ヽハ
          く  / /!   |   〃 _/__ l|   | |   |  |  | | ||ヽ
           \l// / |  /|'´ ∧  ||   | |ー、||  |  | l | ヽ
            /ハ/ |  | ヽ/ ヽ | ヽ  | || /|ヽ/!  |/ | ヽ
            / |  ||ヽ { ,r===、   \| _!V |// //  .!   |
            | ||   |l |ヽ!'´ ̄`゙   ,  ==ミ、 /イ川  |─┘
            | ハ||  || | """ ┌---┐  `  / //  |
            V !ヽ ト! ヽ、    |     !    / //| /
               ヽ! \ハ` 、 ヽ、__ノ    ,.イ/ // | /
    ┌/)/)/)/)/)/)/)/)/)/)lー/ ` ー‐┬ '´ レ//l/ |/
    |(/(/(/(/(/(/(/(/(/(/│||      |\  〃
  r'´ ̄ヽ.              | | ト    /    \
  /  ̄`ア             | | |  ⌒/     入
  〉  ̄二) 知ってるが    | | |  /     // ヽ
 〈!   ,. -'                | | ヽ∠-----', '´    ',
  | \| |   .お前の態度が   | |<二Z二 ̄  /     ',
  |   | |               _r'---|  [ ``ヽ、      ',
  |   | |   気に入らない >-、__    [    ヽ      !
  \.| l.              ヽ、      [     ヽ    |
    ヽ|              \    r'     ヽ、    |

101 :デフォルトの名無しさん:2008/06/12(木) 19:45:00
VBA最近勉強し始めたものです。ネットで入門とかいろいろあさったですがよくわかりませんでした(汗)

質問1.マクロに登録したショートカットやVBAのプログラムって、指定ファイルの指定シートだけで有効にするにはどうすればよいのでしょうか?
VBAの画面で、左に出ているオブジェクトのSheet1とかに目的のプログラム書いただけでは駄目なのでしょうか?
例えば、「セルA1の内容を消去」をCtrl+zに登録したとき、同時に他のエクセルファイルやシートを選択時、Ctrl+zでも
「セルA1の内容を消去」が実行されないようにしたいです。

質問2.同じセルで入出力兼用にするにはどうすればいいですか?後、入出力で同じセルのフォントを変えることできますか?
例えば、B1=A1+5は必ず成り立つとして、先にA1に10を黒字で入力したらB1に15という数字が赤字で表示され、また先にB1に
7を黒字で入力したらA1に赤字で2よ表示されるみたいなのがやりたいです。

恐らく、すごく初歩の質問だと思いますが、誘導でも構いませんので何かご教授いただければありがたいです。
よろしくお願いします。


102 :デフォルトの名無しさん:2008/06/12(木) 19:51:27
VBAでプログラムに興味もったがExcelVBAでなんでもできすぎて他のに興味がいかない。

103 :デフォルトの名無しさん:2008/06/12(木) 20:26:18
>101
マクロのはじめの方にカレントブック、カレントシートを取得する部分を書いて、
処理を許可する対象のブック、シートと同じなら処理を続ける、異なるなら
マクロを終了するという分岐を入れたら?
ブック名とシート名の取得は↓を参考にしてください。
Sub test_sub()
  MsgBox ("処理対象のブック名は : " & ActiveWorkbook.Name)
  MsgBox ("処理対象のシート名は : " & ActiveSheet.Name)
End Sub


104 :デフォルトの名無しさん:2008/06/12(木) 21:21:19
>101
質問2の方
以前のスレのFAQを参考にしてみました。
シートに以下のマクロを書いて、適当なセルに数字かなにか入れてみてください。
セル位置と入力した内容をメッセージボックスに表示する処理です。
Private Sub Worksheet_Change(ByVal Target As Range)
 Dim adr As Variant, naiyo As Variant
 Application.EnableEvents = False
 adr = Target.Address
 naiyo = Target.Value
 Application.EnableEvents = True
 MsgBox ("セル位置:" & adr)
 MsgBox ("セル内容:" & naiyo)
End Sub
セル書式の設定はマクロの記録をやってみてね。
以上

105 :デフォルトの名無しさん:2008/06/12(木) 21:43:20
>>96さんありがとうございます。
今までの書き込みは全て”リセット”という意味で書きました。
問題を単純化し応用したいためです。なので90日は要件から外しています。
私自身の要件がしっかりしてなくてすみません。
A列:日付2008/1/1〜2009/3/31
B列:休みの印を付ける欄(4月1日が休みだったらその横にあるB列に「休」と入れるだけ
C列:何日後といった規則性は全くありません ”手作業”で適当に日付入れるところです。
D列:C列の3稼働日を出すセルです。
方法がどうしたらよいか想像がつきません。
このような結果が欲しいというのを見てもらった方がいいかもしれません。
http://briefcase.yahoo.co.jp/bc/robert_kubica_bmw/vwp2?.tok=bclxRHbB_q.izEUN&.dir=/&.dnm=%b2%d4%c6%af%c6%fc.xls&.src=bc

106 :デフォルトの名無しさん:2008/06/12(木) 22:35:46
>105
こんなんでどうですか?
ところで、アップされたブックのファイル名はなんだったんですか?文字化けしてたようですが。
Option Explicit
Dim Tate1 As Long, Tate2 As Long, c_shift As Long, i As Integer
Sub sample()
  c_shift = 2 ' A2からカレンダー始まる
  Tate1 = 2 ' B列の開始行位置
  Do
    If IsDate(Cells(Tate1, 3).Value) Then ' C列の値が日付かどうか
      Call D_day(Tate1)
      Tate1 = Tate1 + 1
    Else
      Exit Do ' 日付じゃなければ処理を終わる
    End If
  Loop While (1)
End Sub
Private Sub D_day(w_Tate As Long)
  Tate2 = DateDiff("d", Range("A2").Value, Cells(w_Tate, 3).Value) + c_shift
  i = 0
  Do
    Tate2 = Tate2 + 1
    If Cells(Tate2, 2).Value = "" Then '営業日だけ
      i = i + 1 'カウントアップ
    End If
  Loop Until (i > 2) '3営業日になったらループ脱出
  Cells(w_Tate, 4).Value = Cells(Tate2, 1).Value ' D列に出力
End Sub
ところで、実際にアップされたブックで実行してみたら、結果が異なる部分がありました。
C3セルの2月10日の3稼働日後は2月15日ではありませんか?(2月13,14日は
「休」ですよ。)他にもいくつも結果が異なっている部分があります。というかほとんど。

107 :デフォルトの名無しさん:2008/06/12(木) 23:16:26
>>102
俺もそう。
内側からの操作の方がやりやすいし、外からやりたい時だけ無料のVBで
適当に動かせば問題なし。

強いて言えば、シートをスクロールさせるプログラムを組み込まないと画面が見づらい程度か。

108 :デフォルトの名無しさん:2008/06/12(木) 23:26:57
>>105です ありがとうございます。
なんとか光明が見えてきましたが・・・
If Cells(Tate2, 2).Value = "" Then '営業日だけ
で実行時エラー1004 アプリケーション定義またはオブジェクトのエラーがでました。
当方Excel97を未だに使用なので原因はこれですか?
ファイル名は稼働日.xlsです。根本的に3稼働日の数え方が間違ってました・・・すみません


109 :105:2008/06/12(木) 23:44:04
>107
Excel97は久しく使ってない。 けど変な動きをするのであれば
コメント部分は消してください。'の前の空白も含めて。


110 :109:2008/06/12(木) 23:45:55
間違えた。
>108だった。
もう寝る。

111 :デフォルトの名無しさん:2008/06/13(金) 09:06:00
>>76
普通は&演算子で連結しない。
だんだんサイズを大きくしていくのはメモリ確保に時間をとられる。

112 :デフォルトの名無しさん:2008/06/13(金) 10:37:33
>>110さんありがとうございます。やっぱりバージョンみたいでした。これを応用して3稼働日前やってみてますがうまくいきませぬ…なんでだ…(;_;)

113 :106,109,110:2008/06/13(金) 12:46:24
>112
Excel97でも問題ないです。現に、1997年ものの日立フローラ(Windows95,Excel97)で
試してみましたがエラーにはなりませんでした。ソースに間違いがあるはず。
Option Explicitを先頭に入れてますか?これで変数の間違いはチェックできます。

自分のフローラは液晶一体型デスクトップですが、昔のパソコンは丈夫ですね。
当時実売価格50万以上もした代物です。Linuxでも入れて見ようかと思ってたとこでした。


114 :デフォルトの名無しさん:2008/06/13(金) 14:18:02
>>111
言ってることはわかるが、コードのエレガントさを取るか
0コンマ0何秒を惜しむかの個人の好みの問題かと

> 普通は&演算子で連結しない。

コレは無い。普通にやる

115 :デフォルトの名無しさん:2008/06/13(金) 14:26:35
>コレは無い。普通にやる
ダメだこりゃ。

116 :デフォルトの名無しさん:2008/06/13(金) 15:36:12
>>111
なるほど、俺も最初はわからなかったがそういうことか。言語が内部でどう処理するか考えてるつもりだったが…
メモリ確保のことまで考えてなかった、教えてくれてありがとう。ループのときは気をつけよう。
VBAのスレなのに言語の仕組みとか機械語とか知ってる人がいるとは…
うかつなこと書き込めないな。ちなみに今回この板の初書き込み。

117 :デフォルトの名無しさん:2008/06/13(金) 20:31:28
>>115
いや、時間がかかるってのは確かだし認めるよ
しかし、実測してみたが100文字を100回(計1万文字)を1万回試行して差は5秒程度
100文字を100回連結しても差は1万分の5秒(0.5ms)だよ

この為に格納用の配列変数を要素分確保して、Excel2000(Excel2002?)から採用のJoin関数を使うのと、
文字列変数を1つ用意してループで直接連結して最初(又は最後)の余計な連結記号を削除するのは、
どちらが正解って問題なのかな?

118 :デフォルトの名無しさん:2008/06/13(金) 20:56:23
Excelのマクロごときでそんな細かい事を気にする奴は神経症

119 :デフォルトの名無しさん:2008/06/13(金) 21:14:19
Textボックスにフォーカスがあたったときに、
あるTextボックスの場合は日本語入力をONにして、
別のTextボックスの場合は日本語入力をOFFにしたいのですが、
そういう制御は可能ですか?


120 :デフォルトの名無しさん:2008/06/13(金) 21:37:38
自己解決

ttp://www.vba-world.com/ime_ctrl.html
すんまそん
ここで書いてありました



121 :デフォルトの名無しさん:2008/06/13(金) 21:52:13
>>120
Excel2000以降ならJoin関数が簡単だし、それより前のバージョンならMidステートメントがデフォ

122 :デフォルトの名無しさん:2008/06/13(金) 22:38:47
>>121
Mid関数の方だよね?

123 :デフォルトの名無しさん:2008/06/13(金) 23:20:18
VBAで作成したファイルが、エクセル終了しないと開けませんorz
拡張子がtxtだと開けるのですが・・・


124 :デフォルトの名無しさん:2008/06/13(金) 23:27:02
>>121は、たとえばA1:A50000に各6文字あるデータを","で連結してみりゃ&演算子がいかに遅いかわかる。
1文字の区切り文字での連結なら>>124が書いてるMidステートメントが最速で、次がString型の一次元配列に格納しなおしてからJoinだ。
Midステートメントが0.15秒、Strng型の一次元配列に格納してからJoinが0.2秒なのに対して&演算子は約:52秒。

125 :デフォルトの名無しさん:2008/06/13(金) 23:40:29
>>127
Midステートメントそんなに速い?
どうやったらJoinより速くなるんだろ?
まだまだ俺は修行不足だな。
まぁ俺は手軽なJoinしか使うつもりはないけどな。

126 :117:2008/06/14(土) 00:13:09
>>124
納得しました、ごめんなさい
半年ROMるよ

127 :デフォルトの名無しさん:2008/06/14(土) 05:07:57
50000回の結合とかどんな場面だよ

128 :デフォルトの名無しさん:2008/06/14(土) 05:10:37
まあぶっちゃけマクロごときで2,3秒遅くなっても問題ない

129 :デフォルトの名無しさん:2008/06/14(土) 07:15:27
>>122
Mid関数じゃなくてMidステートメント
ただしVB6まで使える技法で.NETでは速くならない。

130 :デフォルトの名無しさん:2008/06/14(土) 07:34:17
>>125
バリバリにチューニング工夫してやっと速くなるが、普通にやるとJoinが速い。
連結はJoinが普通だね。

131 :デフォルトの名無しさん:2008/06/14(土) 09:57:34
キモ

132 :デフォルトの名無しさん:2008/06/14(土) 10:33:49
向上心のないやつは自分の知らないこと書かれると気分が悪くなるよなw

133 :デフォルトの名無しさん:2008/06/14(土) 10:47:22
貧民的プログラミングってやつだねえ
がんばれよ

134 :デフォルトの名無しさん:2008/06/14(土) 10:48:02
>>130
まさか必要な長さの文字列を最初用意するとき、String$関数使って(6+1)*50000-1個の","を用意するんじゃないよな?
それならMidが速いのは俺でもわかる気がするが。
それとも2回ループ回してもMidが速いの?

135 :デフォルトの名無しさん:2008/06/14(土) 11:07:58
MidはさておきJoinは貧民的じゃねーな。
ってか昔はMidは常識だったんだが。

136 :デフォルトの名無しさん:2008/06/14(土) 13:58:58
MidとかLeftとかきもいよ。
いーかげんベーシックなんて捨ててほしい

上っ面だけお化粧(?)して実態はただのパクリで出来た言語の呪縛
パくるしか脳のないゲイつ君。
化粧かどうかも怪しい。

既にC言語で解決されてきたポインタやステートメントなどの言語仕様を
なぜ新たに別のキーワードでリプレイスするのか。
その結果、脳内置換しながらプログラムする不便さだけしか感じない。

switch文をselect caseにしたからって何か良いことあるのか考えてほしい
MSはもっと意味のある新しいものを作れよ



137 :デフォルトの名無しさん:2008/06/14(土) 14:06:16
>>134
各セルが6文字ときまってりゃそうするが、何文字かわからなくても動くように2回ループ。
Len関数は最初のループで使うだけ。
2回Lenを使ってもたいして時間はかからんが。

138 :134:2008/06/14(土) 17:10:15
>>137
そうなのか。
色々やってみるが、どうも俺の実力じゃJoinより速くならん。
諦めてJoin使うことにする。

139 :デフォルトの名無しさん:2008/06/14(土) 17:55:03
>>112です色々ありがとうございます。要件を変えてみて3稼働日前を出したいのですがうまくいきません。
3稼働日前がでるつもりで計算をしているのですが何故か3稼働日以上マイナスしてしまっています。
また閏年の所を空欄にしているのですが空欄にしてしまうためおかしくなってしまいます。
どなたかご教示いただけないでしょうか。(泣)
http://briefcase.yahoo.co.jp/bc/robert_kubica_bmw/vwp2?.tok=bcNR4HbBuvqy__Ra&.dir=/&.dnm=6.14.xls&.src=bc

Dim Count As Integer
Dim k As Long
Dim n As Long
   n = 12

     Do While Cells(n, 7) <> ""
       k = DateDiff("d", Range("D12"), Cells(n, 7)) - 2
       Count = 0
     Do
       If Cells(k, 6) <> "休" Then
       Count = Count + 1

       If Count = 3 Then
         If IsDate(Cells(k, 7)) Then
         Cells(n, 8) = Cells(k, 4)
         End If
       Exit Do
       End If
     End If
k = k + 1
Loop
n = n + 1
Loop
End Sub

140 :106,109,110,113:2008/06/14(土) 18:43:44
>139
106のままではだめですか?
カレンダー(連続した日付)は連続してないとだめです。うるう日をあけるとおかしくなります。
1月1日の日付を表す数値(39083)とG列に入れた日付を表す数値(G12ならば39112)の差を元に
G列に入れた日付がD列のどこになるのかを計算で求めているからです。カレンダーが連続して
ないのであれば、G列に入れた日付がD列のどこになるのかを求める処理も加えなければなりません。

ソースをみましたが、これで動きますか?
Do While Cells(n, 7) <> "" は Do While Cells(n, 7).Value <> "" でしょう。
他すべて .Value が抜けてますよ。
「何故ここで止まってしまうか理解できません」は、Cells(21,7).Value が ""で、ループ継続の
条件からはずれるからです。G列に空欄がありうるのであれば、ループの終了条件を明記したうえで
3日前の日付を求める処理をIf文で実行しないようにすべきです。

もう一度105で示されたブックと106の内容で試してみてください。エクセル97で動くことは
私の1997年ものPCで確認してます。ただし、各ソースの左側の空白は2バイト空白を入れている
のでタブなり半角スペースで置き換えてください。そしてG列は空白セルを入れないようにしてください。


141 :106,109,110,113,140:2008/06/14(土) 18:52:25
よく見たら、また3日「前」になっている。おちょくられているような気がするのでもうやめた。
あとは自分で考えて!

142 :デフォルトの名無しさん:2008/06/14(土) 20:55:21
横レスだが、質問回答は誰が誰でかよくわからないwww
おそらく、if文の判別式が正しく動いてないだろうから、自分で調べるのが最善。
定義と判別式がマッチしていないから、要求された動きが出来ていないと読んだよ。


143 :デフォルトの名無しさん:2008/06/14(土) 21:00:02
だから稼働日に連番をふればいんだってば

144 :デフォルトの名無しさん:2008/06/15(日) 02:27:04
本当にすみません。私自身がグチャグチャで混乱して迷惑をかけてしまって・・・
>>141さん本当に親切に考えていただいて感謝しています。
>>112であるように似たような課題を与えていただいて逆のバージョンの「前」を
応用して作ってみていたわけですがどうもうまくいかず。
出来るだけ自分の物にしようと試みたのですがそれが逆に迷惑をかけてすみません。
本当におちょくってはいないので許してください。


>>143さんありがとうございます。
稼働日に連番をふればいいとのことですが手作業入力した日にたいしてどう稼働日
をふればよいのでしょうか?初心者ですみません・・・

145 :143ではないが:2008/06/15(日) 08:45:42
連番をふるのは 手作業入力した日 じゃなくて 140で書いてるカレンダー の方でしょ。
普通のサラリーマンの勤務形態でいえば、1/1〜1/3は年始休暇、1/4(金)が1、1/5,6が土日の休で
1/7(月)がやっと2、という風にカレンダーの隣の列の勤務日に最初に一連番号を入れておく。
先にそういうことをやっておいてから 手作業入力した日 が一連番号のどこに相当するのかを
調べて、3日前だったら−3した一連日に相当する日付が求める答えになる。
ただし、手作業入力した日 が休みの日だった場合は一連日がないので−3しようがない。
先に示された106で3日後の処理がちゃんと動くかどうかを先にすべきでは?
これを3日前にするのは一カ所 + を − に変更するだけなんだけど。

146 :デフォルトの名無しさん:2008/06/15(日) 10:16:31
143
横レスやけど連番ふるのは無理やで〜
145も言ってるけど該当した場合の処理が面倒や

147 :デフォルトの名無しさん:2008/06/15(日) 10:31:41
日付 休日 連番 手入力した日  修正した手入力した日  3稼働日後
4/1      1    4/1       4/1              4/5
4/2      2    4/2       4/2              4/6
4/3 休        4/3       4/2              4/6
4/4      3    4/4       4/4
4/5      4    4/5       4/5
4/6      5    4/6       4/6

手入力した日が休日で、連番のない日だった場合は、直前の連番がある日を
修正後の手入力した日とする。3稼働日後は修正後の手入力した日の連番に+3すればおk


148 :デフォルトの名無しさん:2008/06/15(日) 10:33:15
それより、休みの日の連番を空欄にするんじゃなく、直前の連番と同じにする方が
簡単かも

149 :デフォルトの名無しさん:2008/06/15(日) 10:41:57
>>136
キーワードはともかく、Select Caseはbreakが要らないのが便利だと俺は思っている。

150 :デフォルトの名無しさん:2008/06/15(日) 11:03:44
>147
日付を手入力するとき、その日付が休みなのかどうか調べる必要があるので(規則性がないらしく
離れた日付だと表をスクロールさせないとわからない場合もある)入力時の手間がかかります。

>148
連番に重複があったらあったで問題があります。
147の表で、3稼働日前 を調べるものとして考えてみます。4/3(休)の連番の列に2を設定
しておくと、仮に手入力した日(修正した手入力した日)が4/6(連番:5)の場合に、
5−3=2 ということで「下から上に」調べていくと4/3が先に該当してしまうんですね。
「上から下に」調べればいいんでしょうが、たった3日前を調べるのに先頭から順に調べていくのは
なんか無駄なような気がする。ちょっとうえのレスでは演算子の違いによるミリ秒の処理時間の違い
のことで論争になってたし。


151 :デフォルトの名無しさん:2008/06/15(日) 11:59:36
全くの初心者の質問ですみません。

Sub syozoku()
Dim busyo As String
Select Case Range("C10").Value
Case "a"
busyo = "総務部"
Case Else
busyo = "正しいコードを入力してください"
End Select
MsgBox busyo
End Sub

これで、C10にaを入力しても、
メッセージボックスに”正しいコードを入力してください”とでます。
Office 2007 professional edition>Excel 2007、windows XPですが、
新たにDLなどが必要なのでしょうか。

152 :デフォルトの名無しさん:2008/06/15(日) 12:14:27
>151
当方WindowsXPのExcel2003ですが、ちょっと確認。
セルC10に1バイト文字の a を入れているのか、2バイト文字の a を入れているのか、
区別してますか?
VBAソースにはどちらを指定していますか?
セルC10の隣(D10セル)あたりに =code(C10) の計算式を入れてみてください。


153 :デフォルトの名無しさん:2008/06/15(日) 12:39:48
1バイトのAでもaでも2バイトのAでもaでも動くようにStrConvとかLCaseとかいろいろ使えばいいじゃん。

154 :デフォルトの名無しさん:2008/06/15(日) 17:54:07
回答有難うございます。
>>152
>セルC10に1バイト文字の a を入れているのか、2バイト文字の a を入れているのか
これは区別しています。

>VBAソースにはどちらを指定していますか?
開いているすべてのブックに保存しています。
作業中のブックにするべきなのかも。

セルC10の隣(D10セル)あたりに =code(C10) の計算式を入れてみてください。
>やってみました。C10に100をいれると49が帰ってきました。
これが原因かも。codeについて調べてみます。

>>153
助言ありがとうございます。
調べてみますが、全くの初心者のためなんのことか分かません。
すみません。

155 :152:2008/06/15(日) 18:19:46
>154
C10セルに a を入れたらどうなるのかを確かめてほしかったんだけど。
それから
 >VBAソースにはどちらを指定していますか?
 開いているすべてのブックに保存しています。
 作業中のブックにするべきなのかも。
の件、誤解してます。VBAソースには a(1バイト)、a(2バイト)のどちらを
指定しているのかを尋ねたのです。ソースを記録している場所のことではありません。

あとは153さんが書いているように、大文字・小文字、1バイト・2バイトを
入れてもOKなようにするには工夫が要ります。153に示された関数(?)をググって
みてください。私もこの板を含むインターネットでずいぶん教えてもらいました。
がんばってください。

156 :デフォルトの名無しさん:2008/06/15(日) 21:51:46
> 大文字・小文字、1バイト・2バイト
Option Compare Textを使うと簡単お手軽な気もするが諸刃の剣
モジュール分ければいいだけの話だけど

157 :デフォルトの名無しさん:2008/06/15(日) 23:43:19
>>155,156
回答有難うございます。がんばってみます。

誤解していた件ですが、どちらも1バイトの文字に間違いありませんでした。
"a"ではなく、case 100 のように、数字で指定しても
case else 扱いになってしまうのです。

158 :155:2008/06/16(月) 00:13:50
>157
うーむ、なんだろ。
考えられる原因としては、C10セルに a_ (_は半角スペースと思ってください)と入力したか、
VBAソースの方の"a"の aの前後どちらか(あるいは両方)にスペースが入ってしまったか、
とにかく比較するふたつが一致しないといけない。
C10セルの書式をプロポーショナルではない(Pのつかない)MS明朝なりゴシックの大きめの
フォントに設定して、本当に1バイト文字になっているかを確認してみてください。

それから 100 は数字としてなのか 3文字の"100"なのかでも変わってきます。 case 100 と
あるのであればC10セルにも数字の 100 と入力しないといけません。
こちらのExcel2003で151のソースを貼り付けてちゃんと 総務部 と表示されたので、ソースの
内容に間違いはないはずです。


159 :デフォルトの名無しさん:2008/06/16(月) 01:12:48
>Select Case Range("C10").Value
>Case "a"

そのコードはちゃんとコピペでこのスレに張ったか?
この部分にスペルとか何か間違いないか?

160 :デフォルトの名無しさん:2008/06/16(月) 01:19:09
出来損ないでスソマソン どうしてもIF文がうまくいかないでつ・・・

F3の値が6で割り切れないとき30行目を削除して割り切れたときはF4の値が6で
割り切れるかみて割り切れないとき40行目を削除ってこれじゃおかすぃ??

Sub limit()

If Range("I1").Value = 0 Then
Range("I1").Value = 1

If Range("F3").Value Mod 6 <> 0 Then
Rows("30:30").delete
Range("I1").Value = 1
Else
If Range("F4").Value Mod 6 <> 0 Then
Range("40:40").delete
Range("I1").Value = 1
Else
Rows("40:40").delete
Rows("30:30").delete
End If
End If
End If

End Sub

161 :デフォルトの名無しさん:2008/06/16(月) 01:42:07
Sub limit()

If Range("I1").Value = 0 Then

Range("I1").Value = 1

If Range("F3").Value Mod 6 Then
Range("30:30").Delete
ElseIf Range("F4").Value Mod 6 Then
Range("40:40").Delete
Else
Range("40:40").Delete
Range("30:30").Delete
End If

End If

End Sub

162 :デフォルトの名無しさん:2008/06/16(月) 01:48:40
>>151
シートの指定がされて無いけど、実行時のアクティブシートが違うとかは無いの?

163 :デフォルトの名無しさん:2008/06/16(月) 09:15:05
>160
実行結果はどうだったの?

それから行削除の処理には関係ないけどI1セルへの無駄な代入文2カ所あり。

164 :デフォルトの名無しさん:2008/06/16(月) 22:06:32
Sheet1の適当なセルにhogehogeと書いて

Sub test()
Dim r
Set r = Sheets("Sheet1").Range("a1:z50").Find(What:="hogehoge", LookAt:=xlWhole, SearchOrder:=xlByRows)
Set r = Sheets("Sheet1").Range("a1:z50").Find(What:="hogehoge", LookIn:=xlValue, LookAt:=xlWhole, SearchOrder:=xlByRows)
End Sub
を実行すると、
WindowsXP SP2, Excell2003 sp3では
1つ目のFindはちゃんと動きますが
2つ目のFindで
 実行時エラー'9' インデックスが有効範囲にありません
と怒られます。LookInを指定すると怒られるようです。

WindowsXP SP3, Excell2000では問題なく意図したとおりに動きます。
Excell2003でもLookIn:=xlValueを指定したいんですが、どうしたらいいですか?

165 :デフォルトの名無しさん:2008/06/16(月) 23:13:54
>164
こちら(XP sp2 Excel2003 sp3)でも同様の症状を確認しました。
対策は・・・誰か詳しい人頼みます。

166 :デフォルトの名無しさん:2008/06/16(月) 23:21:34
LookIn:=xlValueをLookIn:=xlValuesとしてみなよ。


167 :164:2008/06/16(月) 23:35:32
http://www.nbcom.co.jp/PC-Support/FAQ/xls/tr/xls052004tr002.shtml

Excell2000で動作を確認しました。Excell2003での動作は明日確認します。

>166
ありがとう

168 :164:2008/06/17(火) 21:43:36
バッチリ動きました。
ていうか、LookIn:=xlValueで動くほうがおかしい。
もっと言えば、実行時エラーじゃなくて、コンパイル時エラーが出てもいい。
xlValueってグラフで使うやつらしい

169 :デフォルトの名無しさん:2008/06/17(火) 21:45:25
いや、ただの定数だし・・・

170 :デフォルトの名無しさん:2008/06/17(火) 22:52:11
>>169
定数を理解してたらこんなこと書かないって

>>168
イミディエイトウィンドウに
?XlValue
って打ち込んでEnterキー押してみ、正体分かるから

171 :デフォルトの名無しさん:2008/06/18(水) 01:24:21
>>164
俺はFindメソッドにxlValueを使ってたDQNを知ってる。
グラフが好きだったから使ってたんだろう。
たまたま動作が同じだからって、たとえばSpecialCells(xlCellTypeConstants)の代わりにSpecialCells(xlFilterCopy)なんてやったら
ヴァカって言われるよな。


>>169
彼が言うようにグラフで使うときのために用意された定数なんじゃない?
x;lAxisTypeクラスってそうなのかな?

172 :デフォルトの名無しさん:2008/06/18(水) 01:30:53
なんか164もDQNみたいな書き込みになったな。
すまんな

173 :169:2008/06/18(水) 06:21:45
>>171
何のために用意されたにしても、ただの定数。
結局、メソッドの引数が不正だったってだけの話なんだから
コンパイル時エラーじゃなくて実行時エラーなのは当然でしょ、って話。
引数には変数や式も使えるんだし。

174 :デフォルトの名無しさん:2008/06/18(水) 10:38:23
最近VBAを触りはじめたのですが、全く分かりません

指定されたファイルがあれば、そのファイルを現フォルダから別のフォルダへ移動させたい。
指定されたファイルが無い場合はマクロを終了。

ファイルを別のフォルダへ移動はできましたが、指定されたファイルを探すのが上手くできません。

別のサイトへ誘導でもかまいませんので、教えて下さい。
よろしくお願いします。

175 :デフォルトの名無しさん:2008/06/18(水) 11:14:01
やだ

176 :デフォルトの名無しさん:2008/06/18(水) 19:22:38
>>174
Sub test()
If Dir("c:\tmp.txt") <> "" Then
MsgBox "存在します。"
Else
MsgBox "存在しません。"
End If
End Sub


177 :デフォルトの名無しさん:2008/06/18(水) 22:57:34
可能でしたらどなたか教えて頂けませんか・・?
Aエクセル起動時のUserForm1が起動して
他のエクセルに切り替えた時にそのUserForm1はHideします
その後、Aエクセルに切り替えた時に再びShowするのですが

UserForm1がアクティブになっているためAエクセルの編集を続行するためには
適当なセルをクリックしないといけません。
試しにShowする時にRange("A1").Select等を試すも結果は同じ

何とか解決する方法はありませんでしょうか?

178 :デフォルトの名無しさん:2008/06/19(木) 10:02:27
>177
4行目の

その後、Aエクセルに切り替えた時に「再びShow」するのですが

この「再びShow」が問題では? Aエクセルの編集をするのであれば
「Hide」したままにしておけばいいだけでは?

それとも、
他のエクセルに切り替えた時にそのUserForm1はHideします
というのが、単に別アプリ(別のエクセル)が前面に出たから見えなくなっただけ
なのでは?


179 :デフォルトの名無しさん:2008/06/19(木) 10:22:14
例えば指定の曜日とかは自動的にフォントを赤にしたりできるけど、
やっぱりマクロでも祝日はムリかな?

180 :デフォルトの名無しさん:2008/06/19(木) 10:44:34
>179
曜日は7日周期だから計算で機械的にもとめられますが、
祝日は機械的にさだまっていません。有名なところでは春分の日、秋分の日。
さらに祝日は法律で定まったり日付そのものを変更したり(成人の日、体育の
日、海の日など)とあるので、エクセルなどに実装するのは無理です。
なので、祝日をマクロで実現するには祝日(たぶん振り替え休日も含めてと
思うが)をリストにしておいてマクロで該当する日をチェックして、エクセル表
の該当する日付のセルの塗りつぶしを行うという手順になります。
リストを用意できるか、リストの変更をどう行うかがカギです。

181 :デフォルトの名無しさん:2008/06/19(木) 11:48:55
うい

182 :デフォルトの名無しさん:2008/06/19(木) 13:50:15
>>179-180
ttp://www.h3.dion.ne.jp/~sakatsu/holiday_logic.htm#VBA

183 :デフォルトの名無しさん:2008/06/21(土) 00:36:23
>>177です
この「再びShow」が問題では? Aエクセルの編集をするのであれば
「Hide」したままにしておけばいいだけでは?

UserForm1はAエクセルの作業時に役に立つボタン等を実装しているので
Showしておかないと不便なのです。。。

他のエクセルに切り替えた時にそのUserForm1はHideします
というのが、単に別アプリ(別のエクセル)が前面に出たから見えなくなっただけ
なのでは?

ちょっと当方の書き方が不十分だったのかもしれません
大前提としてAエクセルで作業中の時はUserFormはいて欲しく
他のエクセルに切り替えた時にはUserFormは不要なので
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
UserForm1.Hide
End Sub
で隠します、そしてAエクセルに戻した時には
UserFormは必要になるので
Private Sub Workbook_WindowActivate(ByVal Wn As Window)
UserForm1.Show
End Sub
で、再び表示されるのですが、その時フォーカスは
UserForm側にいてセルにいないので
いちいち、セルをクリックしてフォーカスをセル側に切り替える必要がある
これが面倒なので、Aエクセルに復帰した時に
どうにかならないものか。。。。と思っています。


184 :デフォルトの名無しさん:2008/06/21(土) 03:40:55
XP Excel2003での質問なんですが

If x = 1 Then GoTo LB1
ElseIf x = 2 Then GoTo LB2

と記述しているのに
「Elseに対応するifがありません。」と出ます。
間違っているところはどこなんでしょうか?
必要があれば追加文若しくは全文出します。


185 :デフォルトの名無しさん:2008/06/21(土) 04:39:11
>>184
Thenの後は改行してみたらどうですか


186 :デフォルトの名無しさん:2008/06/21(土) 10:45:43
>>185
おま…MSに消されるぞ

というかGotoなんか使うな

187 :186:2008/06/21(土) 10:46:07
>>185
>>184

188 :デフォルトの名無しさん:2008/06/21(土) 13:47:40
>>185
ありがとうございます!
その部分はそれで解決したっぽいです

189 :デフォルトの名無しさん:2008/06/23(月) 13:26:30
Sub Copytest()
Sheet2.Visible = xlSheetHidden
Sheet3.Copy after:=Sheet1
Sheet2.Visible = xlSheetVisible
End Sub

こうやるとsheet3(2)がsheet2の後に追加されてしまいます
Sheet1の後(Sheet2の前)にSheet3のコピーしたいのです

要は隠されてるシートの前にシートのコピーを挿入したいんです
今はSheet2のVisibleプロパティを一旦HiddenからVisibleに、
copy処理してから再びHiddenに戻すという方法をとってるんですが
もっとスマートな方法はないものでしょうか?



190 :デフォルトの名無しさん:2008/06/23(月) 14:51:32
>>186
俺はバンバン使ってたよ、20年前に、ポケコンで、懐かしい・・・

191 :デフォルトの名無しさん:2008/06/23(月) 18:07:07
excel2007でマクロを今は亡きツールバーに登録するマクロが含まれるアドインを使ったら
消せなくなってしまった。消し方を教えてください。

この方法で追加したのを↓

Dim o_cmdbar As CommandBarControl

On Error Resume Next
Application.CommandBars("Worksheet Menu Bar").Controls("あ").Delete
Set o_cmdbar = Application.CommandBars("Worksheet Menu Bar").Controls. _
Add(Type:=msoControlPopup)
o_cmdbar.Caption = "い"
With o_cmdbar.Controls.Add(Type:=msoControlButton)
.Caption = "う"
.OnAction = "え"
End With

本来はこれ↓で消すはずだった。
Application.CommandBars("Worksheet Menu Bar").Controls("メニュー").Delete



192 :デフォルトの名無しさん:2008/06/23(月) 18:08:24
↑だけど追記で。アドインっていうリボンの中に作られたメニューを消したい。

193 :デフォルトの名無しさん:2008/06/23(月) 19:49:14
そりゃツールバーじゃなくてメニューバーだ
そしてそのコードじゃExcelのバージョンがいくつでもマトモに動かんよ

194 :デフォルトの名無しさん:2008/06/23(月) 21:32:42
>>189
ただ単純にbefore:=sheet2で解決しない?
ただし、実際に動作確認してないから分からないけど。

195 :デフォルトの名無しさん:2008/06/23(月) 21:39:50
>>194
実はそれも同じ結果になってしまいまして
どうしてもHideされたシートは自身の前位置を譲ってくれません
Worksheets.Addで追加する場合は問題ないんですけどね
なんなんだろう?

196 :デフォルトの名無しさん:2008/06/23(月) 22:02:55
>>195
じゃあ、コピー処理した後に並べ替え処理したらどうかな?

197 :デフォルトの名無しさん:2008/06/23(月) 22:20:50
ありがとう
並べ替えのループ処理に頼らなくても
一旦VisibleとHiddenを切り替えて、その間コピー処理することで一応解決はできてるんですが
なんだか不細工だなあと
仕様ということ納得します

198 :デフォルトの名無しさん:2008/06/24(火) 18:16:18
>>197
その気持ちわかる、俺も別の件ですっきりさせようとしたがむりで仕様ということで納得した

199 :デフォルトの名無しさん:2008/06/25(水) 22:00:12

VBAでセルの色などを変えようすると”実行時エラー 1004”と出てしまいます。
シートを保護してますが、そのセルのロックは外してます。

他に何か原因はあるでしょうか?

200 :デフォルトの名無しさん:2008/06/26(木) 07:54:34
その部分のソース貼れ

201 :デフォルトの名無しさん:2008/06/26(木) 10:05:57
こんなです

Private Sub Worksheet_Change(ByVal target As Range)

'雇用形態のセル
Dim formRange As Range
Set formRange = Range("A1")

'雇用形態のセルを塗りつぶしなしにする
With formRange.Interior
.Color = vbRed
End With

'オブジェクトの解放
Set formRange = Nothing

End Sub



202 :デフォルトの名無しさん:2008/06/26(木) 10:49:48
質問です。よろしくお願いいたします。

あるセルに設定されている「入力規則」の値を全て取得することは可能でしょうか。

203 :デフォルトの名無しさん:2008/06/26(木) 11:01:15
>>201
シートを保護するときに、"セルの書式設定"のチェックを入れないとダメなんじゃ。

204 :デフォルトの名無しさん:2008/06/26(木) 14:39:34
>>203
2003とかならそうだと思う。状況からみて2003あたりを使ってそうだけど。
勘違いでなければ、2000あたりはそのチェック項目が無いような気がしたので、汎用性を持たせるなら一回シートの保護自体を解除して処理した方がいいと思う。
そして、処理終了後に再度、シート保護処理を実行する。

205 :デフォルトの名無しさん:2008/06/26(木) 14:41:50
>>201
処理と説明が合ってないよ。
塗りつぶしなしにするって書いてるけど、処理自体は赤くするになってるよ。

206 :デフォルトの名無しさん:2008/06/26(木) 16:15:33
>>203
うまくいきました。
ありがとうございます。

>>204
やはり、その方法の方がいいでしょうか。
ありがとうございます。

>>205
すみません。


207 :デフォルトの名無しさん:2008/06/26(木) 16:38:53
二つのBookを用意して、呼び出し元から、呼び出し先Bookのシートにある
メソッドを実行したいと思いますが、出来ません。ご教授ください。



呼び出し元Book.xls
 Sheet1

Workbooks.Open Filename:="呼び出し先Book.xls"
Set wk = ActiveWorkbook

Call wk.Sheets(1).DoExecute() 'エラー

呼び出し先Book.xls
 Sheet1

  Public Sub DoExecute()
Msgbox "Hello"
End Sub



実行時エラー40036:アプリケーションの定義またはオブジェクト定義のエラーです。
と表示されます。



208 :デフォルトの名無しさん:2008/06/26(木) 16:59:59
俺の人生はエラーですがどうすれば直りますか


209 :デフォルトの名無しさん:2008/06/26(木) 17:49:55
あるPublic関数を、ユーザー定義関数の用法でワークシート上から駆動させたとき、
関数内のWorkbooks.Openメソッドがうまく機能しない、という状況について、
ご意見を伺いに来ました。
ちょっと長文になってしまいましたが、聞いてください。

月ごとの売上データが保存されているExcelブックがあって、
それぞれ次のようなブック名で保存されています。
( 2007-04.xls, 2007-05.xls, 2007-05.xls … )
これらのファイル群から、ある特定の月の売上金額を抜き出す
Uriage関数を書いたんです。
たとえば #2007/4/1# を引数で渡すと、07年4月の売上金額が
戻ってくるような関数です。関数の中身はとても単純で、
1)渡された日付をもとにどのブックを開くべきか判断
2)そのブックを開く(Workbooks.Openメソッド)
3)必要な値を読み込む
4)ブックを閉じる
5)値をリターンする
という流れになっています。
この関数、他プロシージャから呼び出して使う分には、
問題なく動作し、なかなか便利です。
そこで、ユーザー定義のワークシート関数として使えるだろうか、
と思い、セルに次のように入力してみました。
=Uriage(2007/4/1)
しかし残念ながら エラー値 が戻ってきました。
処理をトレースしてみたところ、2)のところでブックが開きません。
どうやら、Workbooks.open メソッドは、ワークシート上の関数から
駆動させた場合は機能しないようなのです。
どうして、このような挙動になってしまうのでしょうか。
またこの他に、ワークシート上からではうまく機能しないメソッドを
ご存知の方はいらっしゃいますか。


210 :デフォルトの名無しさん:2008/06/26(木) 18:39:18
これかな
http://support.microsoft.com/kb/170787/ja

211 :デフォルトの名無しさん:2008/06/26(木) 19:08:07
>>208
一度、小学生にダウングレードして再起動

212 :デフォルトの名無しさん:2008/06/26(木) 20:32:38
ハァハァしかけたけど、野郎なのか。だったら市ね

213 :209:2008/06/26(木) 21:55:59
>>210

ありがとうございました。まさにそれです。
そういう仕様になっているということが
たいへん良く分かりました。

ちなみに、色々試してみたら、
テキストファイルのopen、read、closeは
ユーザー定義関数からでも上手くいくようですね。
Excelブックを開くより、読み込みがかなり速いので、
けっこう重宝しそうです。



214 :sage:2008/06/26(木) 22:10:15
>>207
Sheetオブジェクトに記述されたプロシージャは、
そのSheetオブジェクト以外の場所からは呼び出せません。

他のブックからも呼び出せるプロシージャを作りたいなら、
まず標準モジュールを追加して、そこにPublic Subプロシージャを
記述します。

作ったプロシージャの呼び出し方については、
"Run"メソッドを検索してみてください。

215 :デフォルトの名無しさん:2008/06/26(木) 22:56:58
A1からC1までをセル結合した状態でInputBoxを使用してA1〜A3までを選択した場合に、
A1:C3になるのですが、これをA1:A3と取得する方法はありますか?ご教授ください

216 :デフォルトの名無しさん:2008/06/26(木) 23:06:09
優秀な方に伺いたいです!
あるブックのシートにあるデータを計算して、
他のブックのシートにその結果を出力したいのですが・・・

'結果を書き込むブック
Set objWb = Workbooks.Open(strFileName)

このようにオープンすると本当に立ち上がって見た目がよくないです。
裏でオープンして出力できる方法はないでしょうか?

どうぞよろしくお願いします。


217 :デフォルトの名無しさん:2008/06/26(木) 23:14:13
>>216
完璧に画面更新が止まってもいいならapplication.screenupdating=Falseを使用すれば開いてるところは見えないはず。

218 :デフォルトの名無しさん:2008/06/26(木) 23:25:25
一つ教えていただきたいのですが、
12
24
35
46
2
34

とあった場合で、
最小値をこの中から探し出し、
その最小値の行番号を出す方法、
もしくは、載っている本を教えていただけますか。
お願いします。


219 :教えてください:2008/06/26(木) 23:30:34
Excelが大好きな婦女子です。
もっぱらワークシート関数と記録マクロを駆使して
仕事で個人的に利用するささやかな入力フォームを作って楽しんでいますが、
最近ExcelのVBAとAccessに興味を持ち始めて独学中です。

そこで質問ですが、ExcelとAccessのVBAが使いこなせるようになったら
"プログラマ"として食って行けるでしょうか?
他の言語は全くわかりません。

現在のところ自分としてはOffice使いに毛の生えた程度の"プチグラマ"
だと思っています。

派遣社員でも、正社員でも構わないのですが、諸事情により
残業が月10時間程度しか出来ません。
VBAオンリーのプログラマでデスマ(すなわち残業)を避けて生きていくことは
可能でしょうか?

誰かVBAプログラマの現状を教えてください。

220 :デフォルトの名無しさん:2008/06/26(木) 23:30:35
>>217
はい、ありがとうございます!
これを使ってなんとか工夫してみます!

221 :デフォルトの名無しさん:2008/06/27(金) 00:49:59
>>218
もっと簡単な方法があるかもしれないけど、俺はプロじゃないからすぐ思いつくのはこの程度かな。
もし良かったらどうぞ。変数も今、適当に付けたから分かりにくいのはごめんね。

Sub 最大表示()
Dim MyRow As Integer
Dim MyRng As Range
Dim Res As Integer
Dim AnsRow As Integer

MyRow = Range("A65536").End(xlUp).Row

Res = 0
For Each MyRng In Range("A1:A" & MyRow)
If Res < MyRng.Value Then
Res = MyRng.Value
AnsRow = MyRng.Row
End If
Next MyRng

MsgBox AnsRow, vbOKOnly + vbInformation, "結果"
End Sub




222 :デフォルトの名無しさん:2008/06/27(金) 01:14:34
>>221

素早い回答ありがとうございます。
早速使わせていただきます。

223 :デフォルトの名無しさん:2008/06/27(金) 01:22:57
俺が婦女子だったら、VBAプログラマなんて、この世に生まれて来た
価値が何ら見いだせないような悲しい人生しないで、男に頼んで
バンバン子供産んで婦女子ならではの人生を謳歌するけどな。

224 :デフォルトの名無しさん:2008/06/27(金) 01:45:30
>>221

早速参考にして、
作ることができました。
ありがとうございました。

225 :デフォルトの名無しさん:2008/06/27(金) 10:23:26
質問があります
VBAで一週間後の日付を出すやり方がありましたら
教えてださい。お願いします

226 :デフォルトの名無しさん:2008/06/27(金) 11:41:23
Sub test()

Range("A1").Formula = "=TODAY()+7"

End Sub

227 :デフォルトの名無しさん:2008/06/27(金) 12:50:27
ツールからマクロの記憶を使いグラフを3つ作成して、VBAで設定し表示する事が出来たんですが、全て同じ箇所、重なって表示してしまうんです。
個別に位置を指定して表示する方法ありますか?

228 :デフォルトの名無しさん:2008/06/27(金) 14:19:01
セルに設定されている、「入力規則」を取得する方法を知りたし。

229 :デフォルトの名無しさん:2008/06/27(金) 17:35:08
>>227


'1つ目のグラフの位置設定(???は位置を示す数値)

ActiveSheet.ChartObjects(1).Top = ???
ActiveSheet.ChartObjects(1).Left = ???

'ChartObjects(2)、ChartObjects(3)に対しても、個別に位置を設定する。 


230 :デフォルトの名無しさん:2008/06/27(金) 17:50:47
>>228
vba validation moug で検索


231 :デフォルトの名無しさん:2008/06/27(金) 17:57:33
>>219
> "プログラマ"として食って行けるでしょうか?

> VBAオンリーのプログラマでデスマ(すなわち残業)を避けて生きていくことは
> 可能でしょうか?

無理、世の中そんなに甘くない

事務職で"ちょこっと重宝"されるくらいで"優遇"すらされない


VBAは君ごときでも使えることからも解るように、使える奴は婦女子の中にも腐るほど居る
他言語一切ダメで、基礎から学んだわけではなく行き当たりばったりで覚えたような奴なら尚更

まぁ、OfficeはOfficeでもVSTOを完璧に使いこなせたら、それだけで食っていけるけどな
それこそ残業云々どころか出社すらせず在宅労働で食っていける
とはいえ、身に付けるだけで食っていけるような技術は、君ごときが容易に手に出来るものじゃないけどな

232 :デフォルトの名無しさん:2008/06/27(金) 19:13:55
>>230
ありがとうございます!

233 :デフォルトの名無しさん:2008/06/27(金) 20:16:03
Userformから呼び出したSubプロシージャ内で
処理を終わらせるにはどうしたらいいですか?

今は戻り値で判定するのに
functionで呼び出しています。

イベントプロシージャに戻らない方法を
教えてください。

234 :デフォルトの名無しさん:2008/06/27(金) 21:41:24
> 今は戻り値で判定するのに
> functionで呼び出しています。
その方法で良いわけだが

> イベントプロシージャに戻らない方法を
> 教えてください。
無いけど

なんでそんなことをしたがるのかねぇ
初心者の考えることはわからん

235 :デフォルトの名無しさん:2008/06/27(金) 21:44:31
Endじゃないの?

236 :デフォルトの名無しさん:2008/06/27(金) 22:04:52
233の説明通りならEndは違う

237 :デフォルトの名無しさん:2008/06/27(金) 23:49:12
XPとWin2000でexcel2000を利用しています。

ユーザーフォームのcommandbuttonではあまりに味気ないので
マウスクリックやエンターキーの両方でフォーカスを取得して操作できる
画像で出来たボタンを作りたいと考えています
(マウスオーバーで色が変わり、クリック時にボタンを押したような画像に差し換わる)

使えるイベントの都合的にframeに背景画像を指定するなどいろいろ考えたのですが
どうもうまくいきません(画像が切り替わらない・エンターキーを押しても他のコントロールに抜けられない等)
何かよい知恵もしくはもっと適切なコントロールオブジェクトはないでしょうか?

238 :デフォルトの名無しさん:2008/06/28(土) 00:30:05
>>224
ならよかったよ。
処理が最大値検索になってるのは意地悪したわけじゃないよ…。
最小値を勘違いして最大値で作っちゃった。ごめん。

239 :デフォルトの名無しさん:2008/06/28(土) 04:03:14
>>219
単価が安いのを我慢できるんなら。

>>231のように、必死で新規参入を妨害しないとやっていけないくらい、
誰にでもできるし、実際たいしたことない。

240 :デフォルトの名無しさん:2008/06/28(土) 05:59:40
>>234
初心者ですみません。
代替案など教えて頂けないでしょうか?

よろしくお願いします。

241 :デフォルトの名無しさん:2008/06/28(土) 18:22:42
H段の階段を「1段」あるいは「1段飛ばし」で上る。上り方は何通りあるか?
これはどのような構文を使ったらいいんでしょう?

242 :デフォルトの名無しさん:2008/06/28(土) 18:52:01
VBAはプログラムじゃないだろ

243 :デフォルトの名無しさん:2008/06/28(土) 18:52:27
6段の階段なら
1−6段飛ばしの6通りってことか

244 :デフォルトの名無しさん:2008/06/29(日) 00:15:51
>>242
うん、VBAはプログラムそのものではなくプログラム"言語"だね
更に言えばプログラム言語の中のマクロ言語に該当するものだな

245 :デフォルトの名無しさん:2008/06/29(日) 08:06:57
>>241
一段飛ばしする回数をnとすると
(n+H-n*2)!/(n!*(H-n*2)!)
通りになる
nを0からH\2までループして結果を足す

246 :デフォルトの名無しさん:2008/06/29(日) 10:55:55
>>243
アホスwwwwww

247 :デフォルトの名無しさん:2008/06/29(日) 22:20:05
>>233
呼び出された処理の最後で
Application.Quitすればいいと思う。
初心者のうちはけっこうこの命令を
知らないからね。入門書にも出てこないし。

248 :デフォルトの名無しさん:2008/06/29(日) 23:53:22
いいわけないだろ
ApplicationをQuitしてどうするよw

249 :デフォルトの名無しさん:2008/06/30(月) 00:00:48
>>248
IF文などの中で強制的に処理を打ち切るには
Application.Quitしかないと思う。
ExitSubだと呼び出し元に戻ってしまうからね。

250 :デフォルトの名無しさん:2008/06/30(月) 02:02:31
マクロを編集する時に、例えば赤のフォントにしろと言われても色番号が分からないの
ですが、どうしたらいいでしょうか?
どなたか教えてください。

251 :デフォルトの名無しさん:2008/06/30(月) 04:12:46
>>250
例えば、A1を赤に塗ってみてイミディエイトウィンドに
?range("A1").interior.color
又は、
?range("A1").interior.colorindex
などと打ち込んでEnterキーを押してみる

252 :デフォルトの名無しさん:2008/06/30(月) 11:03:07
誰から赤のフォントにしろって言われるの?

253 :デフォルトの名無しさん:2008/06/30(月) 11:47:58
色の設定画面のトコをプリントスクリーン>ペイントに貼り付けて切り取って拡大してA4に印刷
手持ちの教本にあった番号表を直接マジックで書き込んで目に付くとこに張ってるアナログ最強

以外と見つからないんだよ色番号表。これは下の二段が無い
http://www.geocities.jp/chiquilin_site/data/files/color_number.html

254 :デフォルトの名無しさん:2008/06/30(月) 16:06:37
>>250
マクロ記録使って実際にその色でセルに色をつければいいだけ。
そしたら番号なんかすぐに分かる。

255 :デフォルトの名無しさん:2008/06/30(月) 19:24:11
>>249
だからってApplicationをQuitしちゃだめだろ
処理を終わらせたいのであってApplicationを終わらせたいわけじゃないんだからw

256 :デフォルトの名無しさん:2008/06/30(月) 19:26:41
だからEndでいいんじゃないの?

257 :デフォルトの名無しさん:2008/06/30(月) 20:28:20
┐(゚〜゚)┌

258 :デフォルトの名無しさん:2008/06/30(月) 20:30:31
だからExit Subの代わりにEndを使えばそこで処理は終わるだろ。
変数は初期化されるがな。

259 :デフォルトの名無しさん:2008/06/30(月) 20:57:57
>>258
EndってEnd Subのことでしょ?
それだと処理は終わるけど呼び出し元に制御が戻ってしまう。
>>233は呼び出し元に戻らずに終わりたいって言ってるんだからさ。
そのためにはApplication.Quitしかないって。

260 :デフォルトの名無しさん:2008/06/30(月) 21:26:56
>>259
そのEndじゃないよ
でもEndもApplication.QuitもNGだけどな

261 :デフォルトの名無しさん:2008/06/30(月) 21:43:22
>>259
違うって。End知らないの?
Exit Subの代わりにEndを書いてみなよ。
そこで処理が終わるから。

ただPublic変数も含めて初期化されるけどね。
セルにでも値を置いておけばいいんじゃないの?

262 :デフォルトの名無しさん:2008/06/30(月) 21:52:18
戻ってもいいようなプログラムにすればいいのに

263 :デフォルトの名無しさん:2008/06/30(月) 21:54:02
戻った後でfunctionの返す値によってExit Subするのが普通だろうね。
Endとかは他の処理にも影響が出てくるからあまり使うものじゃない。

264 :デフォルトの名無しさん:2008/07/01(火) 00:00:49
すみません リストの入力規則で
リストを指定するのですが、 リストのまん中ぐらいを最初に表示したいので
す どうすればよいでしょうか。

265 :デフォルトの名無しさん:2008/07/01(火) 00:50:47
VBAの課題が全くわからないので教えてください。

はじめて質問させていただきます。

課題1:国語、数学、理科、社会の50人分の点数が掲載してあります。このデータを用いて次の処理をするプロシージャを完成させなさい。国語、数学、理科、社会の50人分のデータの平均点、偏差値を画面上に表示する。
課題2:出席番号が変化するデータに対して、国語、数学、理科、社会の平均点、偏差値を画面上に表示する。

ちなみにデータは
b2に出席番号 c2に国語 d2に数学 e2理科 f2社会と入力されてます。
次にb3〜b52にNo.1〜No.50の出席番号 c3〜c52に国語の点数 d3〜d52に数学の点数 e3〜e52に理科の点数 f3
〜f52に社会の点数が入力されています。
点数は問題に関係ないと思うのでここでは書きません。
また、表示にはメッセージボックスを使うようです。

この2つの問題のプロシージャを教えていただきたいです。
どうかよろしくお願いします。
できれば、プロシージャ1行ごとに簡単な解説も付けてもらえたら嬉しいです。

266 :デフォルトの名無しさん:2008/07/01(火) 01:26:46
>また、表示にはメッセージボックスを使うようです。

ゲラゲラ

267 :デフォルトの名無しさん:2008/07/01(火) 03:34:26
>>251,>>253
ありがとうございます。

>>252
FOM出版に言われましたW

268 :デフォルトの名無しさん:2008/07/01(火) 07:13:09
>>266
わからないから笑って誤魔化すんですね(^-^;)
>>265お願いします。

269 :デフォルトの名無しさん:2008/07/01(火) 07:44:27
宿題(しゅくだい)は自分(じぶん)でやりましょう。

270 :デフォルトの名無しさん:2008/07/01(火) 07:50:32
>>265
>>1★5

271 :デフォルトの名無しさん:2008/07/01(火) 08:11:00
実際なんとなくやったのがこれです。
Sub 国語平均()
Dim 平均 As Single
Dim 偏差値 As Single
和 = Application.WorksheetFunction.Sum(Range("c3:c52"))
数量 = "50"
平均 = 和 / 数量
MsgBox 平均
End Sub

偏差値は定義してますが、計算式がわからないので入力していません。
50人分の偏差値はどうだせばいいのでしょうか?

いろいろ失礼なことを言って申し訳ございませんでした。
明日までの課題ですから焦っていました・・・

272 :デフォルトの名無しさん:2008/07/01(火) 09:22:30
>>264
「入力規則のリスト」はドロップダウンリストという分類の物で
ドロップダウンリストには入力規則のリスト、フォームツールのコンボボックス、
オブジェクトのコンボボックスなどいろいろあるが
手軽な代わりにあまり弄れないのが入力規則のリスト、
多少面倒はあるがいろいろ弄れるのがオブジェクトのコンボボックス

入力規則のリストでは君の望むことは基本的に出来ないから
オブジェクトのコンボボックスを使いましょう
DropButtonClick イベントで ListIndex プロパティを (ListCount \ 2) にしてやれば
全項目中の真ん中が、表示されるリストのトップにくるようになる

>>271
> 偏差値は定義してますが、計算式がわからないので入力していません。
> 50人分の偏差値はどうだせばいいのでしょうか?
「計算式」というのは数学の問題であって、Excelの問題でもVBAの問題でもない
つーか、ワークシート関数として用意されてるわけだが…

それにしても酷いコードだな
最近では小学校でも算数ではなく数学なんだっけ?

273 :デフォルトの名無しさん:2008/07/01(火) 10:19:42
>>272
酷いコードですか…ならどういう風なコードにすればいいか教えていただけないでしょうか?
まず自分はコードがわからないんですけどね…

274 :デフォルトの名無しさん:2008/07/01(火) 10:51:49
>>271
WorkSheet関数を使うのなら、averageとstdevを使えばOK.

>>273
例えば数量に文字列をセットするなんて、論外だ。

275 :デフォルトの名無しさん:2008/07/01(火) 11:02:37
>>274
なるほど。
つまり、出席番号の1〜50も数式?を使ってやった方がいいんですね。
そのやり方も考えてみます。
関数も今は学校なので家に帰ったら試してみます。

276 :デフォルトの名無しさん:2008/07/01(火) 19:36:30
小学校からやり直した方がいいよ

277 :デフォルトの名無しさん:2008/07/01(火) 21:38:04
>>250

>>251 >>253 でOKだと思いますが、私からも補足。

Range("a1").Font.Color = vbRed

という書き方もできます。
vbRedは、カラー定数(ColorConstants)と呼ばれるもの。
他にvbBlack、vbBlueなど基本的な8色がカラー定数として
定義されているので、赤青黄ぐらいの区別なら、
これを使ってコーディングするのが楽だと思います。

8色の内容については、
VBAEditorから[表示]→[オブジェクトブラウザ]で
オブジェクトブラウザを開き、"ColorConstants"で
検索してみてください。



278 :デフォルトの名無しさん:2008/07/01(火) 21:47:52
カラー定数はVBではいいがVBAでは罠がある
人には奨めない方がよろし

279 :デフォルトの名無しさん:2008/07/01(火) 22:19:02
>>278
横からすんませんが、「VBAでは罠がある 」というのは何でしょう?

280 :y:2008/07/01(火) 22:27:26
>>237

CommandButtonの背景画像を切り替えてみてはどうでしょうか?

CommandButton1.Picture = LoadPicture("画像ファイルのパス")

で、指定した画像に変わります。
画像を3つ用意して、
(1.通常時 2.マウスオーバー時 3.クリック時)
以下のイベントのタイミングで切り替えます。

初期設定         →1
CommandButton1.MouseMove →2
CommnadButton1.MouseDown →3
CommandButton1.MouseUp  →2
UserForm1.MouseMove    →1


281 :277:2008/07/01(火) 22:30:01
>>278
えっ、何ですかそれ!?
私も知りたいので、教えてくれませんか。

バージョンによって定数が示す値が違うとか?


282 :237:2008/07/02(水) 15:46:14
>>280
ありがとうございます
実はCommandButtonコントロールを使う方法は真っ先に思いついたのですが
背景画像を変えても「四角い輪郭」までは消えないせいでどうにも残念な外観になってしまい
意味がありませんでした。

試行錯誤しましたが最終的にlabelコントロールを4つCommandButtonの輪郭の上に貼って
隠すことにしました(環境の違い等でズレたりしないかが一番心配)

283 :y:2008/07/02(水) 22:27:45
>>282
私もPictureコントロールで試してみましたが、
確かにうまくいかないですね。

MouseDownイベントプロシージャ内で、
LoadPictureメソッドが正しく機能しないようですが、
こういう仕様なんでしょうかね。

Labelで輪郭消しとは、すごい力技!


284 :デフォルトの名無しさん:2008/07/03(木) 12:55:09
>>281
俺はエクセルVBAを趣味で使ってるだけだから断定できないが
エクセルは2003まで56色しか使えなかったからカラー定数使っても
56色の中の似た色に変換されてしまうからではないかと思う
(カラーパレット変えれば対応できると思うが同時に使えるのは56色って事かな・・・)

285 :デフォルトの名無しさん:2008/07/03(木) 20:27:16
6行目中ほどに配置したコマンドボタンが、左右への列移動に伴って、同様にして左右に移動
=画面の中ほどにコマンドボタンがいつもあるようにする。
には、どう書いたらいいですか?
今は、検索して探したものを元に、
commandbottun1 bottun=1 bottun=2で移動するだけで画面からすぐ、隠れてしまう状態です。

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


286 :デフォルトの名無しさん:2008/07/03(木) 21:47:25
>>285
>画面の中ほどにコマンドボタンがいつもあるようにする。


コマンドボタンがD列にあるとして

range("D6").select
activewindow.freezepanes = true

287 :デフォルトの名無しさん:2008/07/03(木) 23:09:38
>>286 レス、サンクス。
ただ、それは、「ウィンドウ枠の固定」のことですよね。
説明が拙かったですが、求めているのは、例えば、アクティブセルが右に5列移動したら、
コマンドボタンも同様に5列移動するという内容のものです。


288 :デフォルトの名無しさん:2008/07/04(金) 08:31:48
>>287
SelectionChangeイベントでActiveCellからOffset指定でコマンドボタンの移動位置を決めれば良い

でもツールバーをフロートで使った方がスマートだな

289 :y:2008/07/04(金) 21:14:06
>>287

>>288さんの言うようなやり方もありますが、
CommandButtonを貼り付けたUserFormを表示させておく方法もあります。
(この場合UserFormのShowModalプロパティはfalseにしておくこと)
どちらがいいかは場合によりけりだと思います。

ユーザー定義のツールバーを使うやり方は、Excel自体の環境を
変えてしまうので、他人に配布したりする場合には検討の余地が
あります。でも個人で使う分には、コンパクトだし、
好きな場所にドッキングできるので、とてもスマートです。

290 :デフォルトの名無しさん:2008/07/05(土) 07:52:39
2007でツールバーなくなっちゃったしねー

291 :デフォルトの名無しさん:2008/07/05(土) 15:12:18
しねとはどういう事だ

292 :y:2008/07/06(日) 00:04:10
>>290
職場の機種更新で、私も2007を使い始めたばかりですが、
ツールバーが使えなくなっちゃったんですか...
日本語の音声読み上げもオミットされたみたいで
ちょっぴり残念。
脱線ごめんね



293 :デフォルトの名無しさん:2008/07/06(日) 01:55:10
VBAからCommandBarオブジェクト等は使えるんだけど、
実際に表示されるのはツールバーじゃなくてリボンのアドインタブなんだー
タブを切り替えて使わなきゃいけないから面倒なんだよねー

294 :デフォルトの名無しさん:2008/07/06(日) 02:38:55
それを手でクイックアクセスツールバーへ追加ってできなかったっけ?

295 :デフォルトの名無しさん:2008/07/06(日) 07:41:46
うん、個人使用でPersonal.xlsbに登録する類のマクロならそれでいいんだけどねー

296 :デフォルトの名無しさん:2008/07/06(日) 19:11:47
VBAの初心者で 困っています。
どなたか教えて頂けるとありがたいのですが

ユーザーインターフェースで
西暦(1900年から2100まで) 月(1から12月) 日(1から31日)
をそれぞれテキストボックスに入力し
ボタンを押したら
曜日を表示させる(テキストボックス?)

というのを作ろうとしているのですが よく分かりません。

具体的には 西暦 月 日 を入力して そこから曜日を割り出す計算式(プログラム)と
うるう年の場合の計算式(プログラム)
が分かりません。

あと 入力するテキストボックスに 規定値いがいの値を入力した場合のエラー表示
もよく分かりません...。

すいません くだらない質問で...m(_ _)m

ただ 本当に困っています。

どなたかアドバイス、参考例など教えて頂けるとありがたいのですが

よろしくお願いしますm(_ _)m



297 :デフォルトの名無しさん:2008/07/06(日) 19:21:32
エクセルならWEEKDAY関数で曜日返してくれなかったっけ???

298 :デフォルトの名無しさん:2008/07/06(日) 21:11:04
曜日によって処理を変えるとかではなく
曜日を表示させるならWeekday関数+WeekdayName関数だな
ついでに年月日を別々のテキストボックスに入力させるならDateSerial関数も必要かな

> あと 入力するテキストボックスに 規定値いがいの値を入力した場合のエラー表示
> もよく分かりません...。
いろんな手法があるので「プログラム 入力制限」とか「VB 入力規制」とかでググろう
アルゴリズムの話なので、VBA以外での話でも応用出来るからね

でも、年、月、日くらいなら、コンボボックスをリスト選択のみの設定で使う方法もある

299 :y:2008/07/06(日) 22:02:51
>>296

年・月・日から、曜日を求める方法はいくつかありますが、
大筋は>>298です。まずは次の関数について調べてみてください。
・DateSerial関数 ・Format関数
これらの機能が理解できたら、次のコードが何をしているかわかるはずです。
(うるう年でも問題ありません)

Sub youbi()
Dim year As Integer
Dim month As Integer
Dim day As Integer
Dim theDate As Date
Dim youbi As String
year = 2008
month = 7
day = 1
myDate = DateSerial(year, month, day)
youbi = Format(myDate, "aaa")
MsgBox youbi
End Sub

(続く)


300 :y:2008/07/06(日) 22:03:31
(続き)

UserForm上のTextBoxに入力されるべき値の範囲を制限する方法について
ですが、まずは新しくUserFormを作って、必要なTextBoxやCommandButtonを
配置するところまではできていますか。

TextBoxに値が入力された時点で値をチェックしたいなら
TextBoxコントロールのChangeイベントを、
CommandButtonが押された時点で値をチェックしたいなら
CommandButtonコントロールのClickイベントを調べて、
イベントプロシージャについて理解してください。

あとは、"TextBoxの値が規定範囲内かどうか調べて、範囲外ならエラー
処理をする"コードを、イベントプロシージャ内に記述するだけです。

301 :デフォルトの名無しさん:2008/07/07(月) 14:50:44
数値データから多項式係数を割り出すのにLINEST関数を使ってます。
でもExcelの仕様で、16項までしか対応しないみたいですよね。
VBA使えば255項とか分析できるのかな?
ググったけど、そういうニーズは無いみたい…。

302 :デフォルトの名無しさん:2008/07/07(月) 15:44:22
そもそも16項もできたっけ? 最近のはできるのかな。
いずれにしても、多項式係数の意味が判っているなら自分で実装できるでしょ。

303 :デフォルトの名無しさん:2008/07/07(月) 18:39:24
質問させて下さい。
OS:winXP SP2
EXCEL ver:2003

【質問内容】
数式1〜3からVBAを使用して
ファイル名、シート名、セルをそれぞれ分割し変数に格納したいです。
どんな方法が適切でしょうか?

数式1⇒=[ブック]シート!$A$1
数式2⇒=[ブック]シート!'!$A$1
数式3⇒=[ブック]シート!!!'!$A$1


現在の処理はDoとMidを使用して左3文字目からIfを使って
1文字ずつ文字判断させています。

"]"がでたら3文字目から"]"の手前までブック名称⇒変数Aへ
"!"がでたら"]"の直後から"!"の手前までシート名称⇒変数Bへ
"!"の直後からはセル⇒変数Cへ

数式1では問題ないのですが、数式2、3みたいに
シート名称に"!"が含まれている場合にシート名称が正常に変数Bに格納されません。

Midを使って"'!"の場合にシート名称を読み込んだとしても、
数式2、3はそれで回避出来ても今度は数式1が認識できなくなってしまいます。

他に良い方法があるのかもしれませんが、全く思いつきません。
わかりにくい文章で申し訳ありませんが、
どうか、ご教授の程よろしくお願いします。

304 :デフォルトの名無しさん:2008/07/07(月) 18:52:31
こちらのスレにて質問させて下さい。

ログファイルから各種括弧(または類するもの)→ () [] 【】 <> 《》 「」
で囲まれた文字列を取り出したいのですが、どのように処理すれば
よいのでしょうか?ログなので、取り出すのは任意の文字列です。

例:
***(aaa)** → aaa
[warning]*** → warning
月火【水】木金土 → 水

305 :デフォルトの名無しさん:2008/07/07(月) 19:12:21
1 FINDで”(”の位置を検索する
2 FINDで”)”の位置を検索する
3 MIDで”(”と”)”の間を抜く
4 かっこの種類だけ繰り返す

306 :デフォルトの名無しさん:2008/07/07(月) 19:47:05
>>303

$で判定するとか

307 :デフォルトの名無しさん:2008/07/07(月) 20:40:17
>>304
regexp

308 :デフォルトの名無しさん:2008/07/07(月) 20:50:48
シート名には「!」だけじゃなくて「$」や「'」、おまけに「[」や「]」も使える。
しかも、それはブック名にも当てはまる。
その辺は考慮しなくていいのかな?

309 :303:2008/07/07(月) 20:57:11
>>306
"$"で判別しても大丈夫だとは思うのですが…
"$"も"!"もシート名称で使えてしまうので、
誰かがそんなシート名称を指定してしまった場合に
対処出来ない様な気がして敬遠してたのですが…


じゃあ…"'!"で存在しない場合に"!$"で判別すれば大丈夫かもですね…

なんだかわかった気がします!
ありがとうございました!

310 :308:2008/07/07(月) 21:03:49
あーでも「[」とか「]」を使ったら参照できないな

> じゃあ…"'!"で存在しない場合に"!$"で判別すれば大丈夫かもですね…
「'!」とか「!$」を含む事もできるけどね・・・

311 :303:2008/07/07(月) 21:58:56
>>308、310
あれ?"'"ってシート名称に使えましたっけ…じゃあ駄目じゃん俺_| ̄|○

ブック名称を格納するときは"!"を見ておらず"]"しか見ていないので
大丈夫かと思ってたんですが…やっぱ駄目ですか?

シート名称は"!"を名称として使用すると"'"が繋ぎ部分に加えられる為、
その辺りで判別しようかなと思ったのですが…どうすればよいのやら…

なにはともあれ、お答え下さってありがとうございました!

312 :y:2008/07/07(月) 22:39:46
>>303

数式1〜3がセル参照として成り立っており、かつ
参照先のブックが開いているという前提なら、
単純な方法があります。

(なお、参照先のブックが閉じられた状態では、>>303
 数式1〜3のようなセル参照は普通はありえません。
 普通は保存して閉じるだろうし、保存して閉じれば
 数式は絶対パスを含む形に自動的に置き換わるからです。)

■考え方
数式1〜3はいずれもセル参照なので、
参照先のRangeオブジェクトを得ることができます。
そこから、Parentプロパティを使って、
親シートおよび親ブックを割り出します。

■具体例
Book1とBook2が開いていて、
Book1のセルA1に
=[Book2]Sheet1!$A$1
という式が設定されているとします。

Dim rg as Range
Dim adr as String, sh as String, bk as String

Set rg = Range(Thisworkbook.Sheets("Book1").Formula)
adr = rg.Address
sh = rg.Parent.Name
bk = rg.Parent.Parent.Name



313 :デフォルトの名無しさん:2008/07/07(月) 22:51:52
Nameと同一かどうかはわからないけどな

314 :デフォルトの名無しさん:2008/07/07(月) 23:17:54
>>311
"'"は繋ぎ部分だけじゃなくて先頭にも加えられない?っていうかつまり"'"で囲まれない?

315 :303:2008/07/07(月) 23:41:30
>>312
仰る通り、現在開いているブック対象にしています。
後々、フォームに組み込もうと思ってまして…
アドインにせずに単体ツールとして運用する予定なので、
必要なファイルは予め開いていて貰うつもりで作っています。


教えて頂いたコードですが、何故か上手く動きませんでした…
Formulaの記述でストップしてしまいます…
(当方2003を使用しています。)
Formuraってバージョン依存ありましたっけ…?
もっとよく調べてみます…


>>314
シート名称からの指定ですと、確かに先頭に"'"は付きますが、
ブック名称からの指定や、フルパス指定だと先頭には"'"はつかないようです。

316 :303:2008/07/08(火) 00:06:35
>>312
サンプルが動きました!
一度Variantで取り出してからRange指定しなきゃ駄目だったみたいです。

これがあればいちいち変なループ処理を組み込まずとも、
それぞれの名称を獲得できますね!

いやはや勉強不足でご迷惑をおかけしました…
皆さん、本当にありがとうございました!!

317 :デフォルトの名無しさん:2008/07/08(火) 09:36:50
regexp使えば楽だったね。

318 :デフォルトの名無しさん:2008/07/08(火) 11:47:39
>>302
>>301です。
VBAでworksheetfunction.linestってのがあった。
これで実装してみたけど、やっぱり16項までが限界だったみたい。
バージョンは2003です。

以上、報告まで

319 :デフォルトの名無しさん:2008/07/08(火) 15:37:59
初歩的な質問なのですが、ブックを超えて操作をさせようとするとどうしても上手く動きません。

book2.xlsを開き

book1.xls の sheet2 A1 の内容を

book2.xls の sheet1 A1 に書き込む

とするにはどう書けば良いのか教えて下さい。

どなたかお願いします。

OS XP
EXCEL2000

320 :y:2008/07/08(火) 16:17:05
>>303

ごめんね。>>312のコードはだいぶ変でした。
Rangeオブジェクトを取得する行は正しくは

Set rg = Range(ThisWorkbook.Sheets("Sheet1").Range("a1").Formula)

でした。でも、自分なりに解決できたとのこと、何よりです。



321 :デフォルトの名無しさん:2008/07/08(火) 16:23:58
emoji1 = InStr(ActiveCell, "か")
emoji = Mid$(ActiveCell, emoji1, 3)
emojip = Worksheets(2).Cells.Find(emoji).Offset(, -1)
ActiveCell.Replace what:=emoji, Replacement:=emojip
このようなマクロで activecell="あかきくお" emoji="かき"だった場合に
置換した後はactivecvell="かきこ"
となってemoji以前がそっくり削られてしまいます
どのように書けばactivecellの中のemojiだけを置換できるのでしょうか?

322 :デフォルトの名無しさん:2008/07/08(火) 16:28:48
>>319
ヒント。

Workbooks.Open ("C:\2.xls")
Workbooks("2.xls").Sheets("sheet1").Range("A1").Value = Workbooks("1.xls").Sheets("sheet2").Range("A1").Value

後は自分で考えれ。

323 :デフォルトの名無しさん:2008/07/08(火) 16:42:09
>>321
それだけじゃ emojiip に何が代入されてるのかも分からないよ。
察するに sheets(2) にデータテーブルを持たせてるのかな。 
"かきこ" も、何故でしょうか。

ちょっと頭がボーっとしてるんで、私が読みきれてないだけだったらごめんね。

それと、位置を代入してる変数に emoji1 だと訳が分からなくなるから気をつけた方がいいかも。


324 :デフォルトの名無しさん:2008/07/08(火) 16:57:17
>>323
ありがとうございます、やはりポイントだけ書き込んでも分かりづらいですよね;
そしてすみません、"かきこ"ではなく"かきお"でした;

sheets(2)はおっしゃる通りで絵文字変換表があります。
A列絵文字を入力して B列絵文字に変換しようと考えたコードなのですが
A>Bはうまくいったものの、戻すのも作ろうとコード丸写しから改編しB>Aのものを動作させると
代入したい部分だけでなくセルの前半ごと変換されてしまいました。

自分用の小さなものなので、変数名は手抜きしています;

325 :デフォルトの名無しさん:2008/07/08(火) 17:38:48
うーん。先ずはもっと小さく組んで、それが上手く行ったら大きくして行かないとデバッグ出来ないかもなぁ。
具体的に言うと、変数には予め代入してしまう。
ActiveCellじゃなくて、変数で文字列を代入しておくといいね。
あと、findする列が決まってるならば、cellsで全体から検索ではなくて、columnsで指定した方がスマートです。

dim hoge as string
dim emoji as string
dim emojiip
hoge = "あかきくお"
emoji = "かき"
emojiip = sheets("sheet2").columns(2).find(emoji).offset(0,-1)

まず、ステップインでF8を押しつつ1行ずつ実行して行って、emojiipに目的の物が代入されたかをチェック。
その後で、
hoge.replace what:=emoji , replacement:=emojiip

こんな感じで、どこにおかしい部分があるかを少しずつ調べて行くと良いですよ。




326 :321:2008/07/08(火) 18:06:54
>>324 済みませんでした
B>A 変換は置換対象の頭に"*"が含まれていて、ワイルドカード扱いになっていたみたいです。
なので前半がそっくり削れていたんですね;;
こういう場合は*以前を別変数に収めておいて、変換後くっつけると言うようにするしかないのでしょうか?

327 :デフォルトの名無しさん:2008/07/08(火) 18:08:37
もう面倒だからRegExpでreplaceしちゃいなYO!!

328 :デフォルトの名無しさん:2008/07/08(火) 18:09:11
うそです

329 :314:2008/07/08(火) 19:17:00
>>315
ああ、うん、ブック名込みで囲まれるみたいだからシート名だけ見ると後ろだけだね
まあもうどうでもいいね

330 :67:2008/07/08(火) 21:43:58
inStrとmidで出来るからやってるんだろうけど、
個人的には正規表現使った方がスマートだと思うんですわ。

あまり正規表現が好まれない理由って何なんでしょうか。

331 :デフォルトの名無しさん:2008/07/08(火) 21:52:46
つーか、好みどうこう言えるのは、自分で解決できる奴の特権
人に聞くなら実用上不都合が無ければ良しとするべき

332 :デフォルトの名無しさん:2008/07/08(火) 22:02:37
303です。
>>320
わざわざ修正後のコードをあげて下さりありがとうございました!
おかげさまでファイル取得が楽になりました。

>>329
すみません…読解力が足りませんでした…
当初の処理だと既に開いているファイル名称を対象に
ブック判断用文字列"]"
⇒"]"が見つかればシート判断用文字列"'"を直後から探す
⇒"'"が見つかれば直後からアドレス
という風に左側から一文字ずつIFを階層にさせていたため、
最初に"'"があったとしても"]"が見つからない限りブック名称とする処理をしてました。
ファイル名で"]"は入力できなかったはずなので
ブック名称は間違えようがないと思って作ってました。

…今考えると凄まじくめんどくさい処理ですね。

そんな感じなので"]"の前にある"'"は処理上認識しないからと頭の中で完結させてました。

ともあれ、アドバイスありがとうございました!
もっと勉強しておきます…

333 :y:2008/07/08(火) 23:17:27
>>330
私の場合ですが、正規表現は何となく苦手なんです。
2〜3回のテストではうまくいくようでも、実際に
いろいろな文字列を処理させてみると、どうやら論理的に
穴があるらしく、意図した結果が得られないことが
よくあります。

表現が回りくどくなっても、文字数や位置をもとに単純な
条件分岐を積み重ねる作りにしておくと、事前チェックや
デバッグの際に、各行をトレースして細かいレベルの動作を
明示的にチェックでき、個人的にはとても安心です。

向き不向きもあるようで、人によっては正規表現でひょひょいと
書いてしまう方もいます。「この式で大丈夫」と確信できるのは、
正規表現の動作を頭の中でシミュレートできるからなのでしょう。
とても羨ましいです。


334 :デフォルトの名無しさん:2008/07/09(水) 01:56:20
配列操作の練習を兼ね、CreateObjectで一時的に作成したシートに
コンボボックスのデータを転記し、ソートした後に配列に書き戻す…
といった事を考えたのですが、

Set myWorkbook = CreateObject("Excel.Sheet")

とした途端、元ブックのウィンドウサイズが変わってしまいます。

Application.ScreenUpdating = False では防げないようなのですが、
どうすれば挙動が見えないようにできるでしょうか?

335 :デフォルトの名無しさん:2008/07/09(水) 02:23:28
ボタンを押すと、変数にA3にある変数を1足したいのですが、

Cells(1, 3).Value = "Cells(1, 3).Value" + "1"

とやっても、増えてくれません。
特に変数は使っていませんが、どのようにすれば、変数の値を増やすことができるのでしょうか?

336 :デフォルトの名無しさん:2008/07/09(水) 02:59:18
>>335 " ← を取ってみ

337 :デフォルトの名無しさん:2008/07/09(水) 03:03:43
>> 335 A3にある変数て何?
セルA3の値なら Cells(3,1).Value Cells(1,3).Value だとセルC3だぞ

338 :335:2008/07/09(水) 03:11:38
変化がありませんでした、私の条件式に問題があると思います。

Sub 今日の日付()

' A1が今日の日付で無ければ、通し番号を1にして、A1値を今日の日付にする

If "Cells(1, 1).Value" <> Date Then
Cells(1, 3).Value = 1
Cells(1, 1).Value = Date
ActiveSheet.Name = Format(Date, "yyyymmdd")

' 今日の日付であれば通し番号を増やす
Else

Cells(1, 3).Value = Cells(1, 3).Value + 1

End If

End Sub

こんな感じです、ボタンを押したら、今日か過去か日付を判断して、
過去なら(つまりはテンプレシートをコピーした直後)
通し番号を1にして、A1の日付を今日に、

すでに今日作っているなら、
通し番号を2にして、シート名を「20080709-2」と「ハイフンと通し番号」を付け加えたかったのです
(ここはまだまだ難しくて未実装)


339 :335:2008/07/09(水) 03:13:00
ちなみに、最初のifで日付が今日で無いときは処理がうまくいっています。
日付が今日なら、どうやらelse以降が実行されていないようです。

>>337
たしかに変数なんて使っていませんね、すいません。

340 :デフォルトの名無しさん:2008/07/09(水) 07:24:02
なぜCells(1, 1).Valueを"で囲む?

341 :デフォルトの名無しさん:2008/07/09(水) 07:39:37
>>338
>340の言うとおり。
Ifのすぐ後ろのCellsを""で囲んでいるのをとる。

342 :デフォルトの名無しさん:2008/07/09(水) 10:06:13
>>304
Sub test()
Dim hoge, hogematch, piyo, hitpat, moji As String
Set hoge = CreateObject("VBScript.regexp")
moji = "月火【水】木金土"
hitpat = "【.*】"
'hitpat = "\(.*?\)" '最小マッチ、\(でエスケープ
'hitpat = "\[.*\]" 'メタ文字でググるとgood
With hoge
.Pattern = hitpat
.ignorecase = True
.Global = True
End With
Set hogematch = hoge.Execute(moji)
piyo = hogematch(0)
piyo = Replace(piyo, "】", "") '加工例1
piyo = Replace(piyo, "【", "")
'piyo = Mid(piyo, 2, 1) '加工例2
Debug.Print (piyo)
End Sub

343 :デフォルトの名無しさん:2008/07/09(水) 10:13:44
コメントは適当に消してね

344 :304:2008/07/09(水) 13:10:31
できました!ありがとうございます!

345 :デフォルトの名無しさん:2008/07/09(水) 16:38:09
ぬお。エクセルで正則表現使えたのか!
恥ずかしながら知らなかった・・・。
横からマジ感謝。

346 :338:2008/07/09(水) 18:09:41
>>340
>>341
くはー、できました!
ダブルクォートで囲むと意味が変わるのですね。
連番で上がりました。

あとは、シート名に連番をつけていくのが目標です。
VBA楽しいですね、
手作業で面倒だった、EXCELが自分専用の便利ツールになりますね。

347 :デフォルトの名無しさん:2008/07/09(水) 18:57:16
ExcelがEXILEにみえてきた

348 :デフォルトの名無しさん:2008/07/09(水) 19:18:04
しばしディスプレイから目を離し、遠くの緑をみつめよう〜。

349 :デフォルトの名無しさん:2008/07/09(水) 22:50:21
Excel2007
WindowsXPsp2

「ズームボタンが押された状態で」印刷プレビューを開くにはどうしたらいいですか?

350 :デフォルトの名無しさん:2008/07/10(木) 00:31:43
Excel-VBA は楽しいだろうが、Excelそのものはあんまし
楽しいものじゃないと思う

351 :デフォルトの名無しさん:2008/07/10(木) 09:29:53
ワードとかパワポなんて仕事でも使ったことねえ

352 :デフォルトの名無しさん:2008/07/10(木) 11:17:53
「Excelで文章書く奴は初心者」



ってのはよく言われる事だが実際には
全然そんなこと無いと思う。
寧ろWordで作る意味が分からない。


353 :デフォルトの名無しさん:2008/07/10(木) 11:38:39
winXP。EXCEL2003
並び替えでの質問ですが、
2008年6月30日
2008年6月2日
2008年6月27日
の文字列としてあるデータを並び替えで昇順にしたいんですが
マクロの自動記録時には正確に
2008年6月30日
2008年6月27日
2008年6月2日
となりますがそのマクロを実行すると
2008年6月30日
2008年6月2日
2008年6月27日
となってしまいます。
コードは
Columns("B:H").Select
Selection.Sort Key1:=Range("B1"), Order1:=xlDescending, Header:=xlNo, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
:=xlPinYin, DataOption1:=xlSortTextAsNumbers
どこをどうやればうまく行くのでしょうか?

354 :デフォルトの名無しさん:2008/07/10(木) 11:39:56
age

355 :デフォルトの名無しさん:2008/07/10(木) 11:47:56
>>352
だよな
会社で扱うファイルのうちワードなんて1割もない

356 :デフォルトの名無しさん:2008/07/10(木) 12:02:41
取り扱い説明みたいなものを書くのにはWordは楽だよ。
これで、アウトラインプロセッサ機能がもう少し使い易ければもっといいのだけれど。
まぁ、原稿用紙が美しいと思う日本人にはExcelで型に填めるのが好きな人が多いのは判らんでもないけど。
数式やコードが入るような文章書くときにも、レイアウトをそれほど意識しないでもいいのは助かるしね。
まぁ、よほどのことがない限りPowerPointは使わないけれど。

357 :y:2008/07/10(木) 17:44:33
>>353
並べ替えを記録する際、きちんと「昇順」を選択していたのなら、
Order1はxlDescendingではなくxlAscendingになっているはずです。

また、自動記録時にその結果になるためには、
「並べ替えの前に」ダイアログボックスで
「数値とテキスト形式の数値を分けて並べ替えを行う」を
選択しているはずです。
その場合、DataOption1はxlSortTextAsNumbersではなく、
xlSortNormalとして記録されるはずです。

以上から、記録したマクロではないマクロを実行している可能性
があります。もし、自動記録を何度か繰り返したのなら、
いくつか似たようなマクロができてしまっていると思いますので、
よく確かめてみてください。




358 :y:2008/07/10(木) 19:02:56
>>352
たぶん、この手の初心者のことを言っているのでは。
ttp://d.hatena.ne.jp/kagamihoge/20060427/1146130613
...誰でも最初は初心者なので仕方ないですが...

Excelは、横幅の描画単位がかなり曖昧です。
セルの書式設定を「折り返して全体を表示する」に
したとき、編集画面ではきちんとセルの中におさまっていても、
プレビューで見るとはみ出て切れてしまったり、
セル幅とグラフオブジェクトの幅が、やはりプレビューで見ると
だいぶ違ったりするのは、やはり文書向きのソフトではないと
感じてしまいます。

でも、Excelも便利だと感じるときもあって、その1つが
行間隔を直感的にリサイズできる点。
Wordにも、行間隔スライダーみたいなツールが実装されたら
すごい便利なのに、といつも思います。

359 :デフォルトの名無しさん:2008/07/10(木) 19:43:32
> 1つのシートに、縦に表1と表2が並べてあるドキュメントなのですが、
> 表1に列を追加しようとしたところ、当然ながら表2にも列が追加されてしまう

これは当然じゃないだろ…

360 :y:2008/07/10(木) 21:15:15
>>349

私の知る限り、プレビュー画面を拡大するメソッドはVBAには
実装されていません(というより、プレビューが開いている間は
VBAの実行が一時的に停止しています)。

力技ですが、ショートカットコマンドを利用する方法があります。
普段はショートカットコマンドを使っていますか?
例えば、[Alt][W][F]の順でポンポンポンとキー入力すると、
ウィンドウ枠の固定ができる、といったような機能です。

うちのExcelは2003なのですが、[Alt][F][V][Z]でプレビュー画面が
ズームされます。これをVBAでは、

SendKeys "%fvz"

と表現できます。詳しくはSendKeysステートメントを調べてみてください。
ただしこれは、Excel2003までの場合です。
2007でも2003以前のショートカットの大部分は生きているので、
このステートメントをそのまま使えるかもしれませんが、
できれば2007のショートカットコマンドを調べて実装したほうがいいでしょう。

なお、SendKeysはアクティブなアプリケーションに対して有効です。
マクロをVBAEditorから実行すると、VBAEditorに対してSendKeyしてしまうので、
実行するときは必ずExcelから実行してください。

361 :デフォルトの名無しさん:2008/07/10(木) 22:36:32
>>357
降順のコードからコピーしてました。
xlSortTextAsNumbers、xlSortNormal
どちらで試しても日付順にはなりません。

自動記録でなパターンを順番に記録して
実際にマクロを実行しても一度も日付順にはならないのです。
EXCELの仕様(不具合)と見たほうがいいのかな?



362 :デフォルトの名無しさん:2008/07/10(木) 23:05:54
バグだの仕様だの、ってのは簡単に言ってはいかんのだ。
それを言った時点で全てが終わりってくらい重く考えないといかんよ。

プログラムは言われた通りの事”しか”やらないんだからね。

363 :y:2008/07/11(金) 06:21:02
>>361

あ、すみません。>>357の私のレスに間違いがありました。
DataOption1についてはxlSortTextAsNumbersでOKでした。
訂正します。

でも、それでもうまくいかないのですか。
(うちではうまくいくのですが...)

364 :デフォルトの名無しさん:2008/07/11(金) 08:27:27
俺はDataOption1とかの使い方は知らないが、そこを無視すると
"2008年6月2日"
"2008年6月27日"
この文字列の大小は9文字目の"日"と"7で"比較されるから、上の方が大きくなるのは当然じゃないのか?
バグでも何でもないと思うんだが。

文字列を日付として大小比較するなら
"2008年06月02日"
"2008年06月27日"
という形の文字列にしないとまずいんじゃないのか?

"2008年12月6日"
"2008年6月30日"
これだと下の方が大きくなるからね。

文字列の大小比較するより、データ、区切り位置、日付でシリアル値に変換した方がいいと思うがね。

365 :デフォルトの名無しさん:2008/07/11(金) 08:45:49
ちょっと訂正
この文字列の大小は9文字目以降の"日"と"7日"で比較されるから


366 :y:2008/07/11(金) 17:06:01
>>364
「数値に見えるものはすべて数値として並べ替えを行う」は
意外に賢くて、日付と解釈できる文字列はシリアル値として
解釈し、並べ替えてくれます。
"2008年12月6日" → 39788
"2008年6月30日" → 39629
と読まれて、きちんと6月が先頭に来ます。
ただし、"2008年0月4日"みたいな変なのは、日付を表す
シリアル値として解釈できないので、昇順で並べ替えても
12月より後ろに来ます。

>>361
...でも正直なところ、>>364の意見に賛成です。
シート上の日付文字列を、どうしても文字列のままにしておかなければ
ならない理由が特になければ、シリアル値に変換してしまった方が
いいかと。日付文字列→シリアル値の変換は、DateValue関数
で簡単にできます。変換さえすれば、昇順の並べ替えも
全く問題なくできるようになるでしょう。


367 :364:2008/07/11(金) 18:29:15
>>366
トンクス。
「数値に見えるものはすべて数値として並べ替えを行う」ってのがあるのか知らなかったよ。
俺の2007の並び替えのオプションじゃ見つからんのだが....。
VBAにはDataOption1とかあるから、ちゃんと実装してるんだろうけど。

それはおいといて>>353のコードで降り順にソートすると、
"2008年6月2日"
"2008年6月27日"
これは>>353のいうようにこの通りに並ぶね。
きちんとシリアル値に解釈できてたらそんなことないはずだけどね。
そんなおかしなオプションは使わないことだろうね。


368 :364:2008/07/11(金) 19:00:54
2007でいろいろ試してみたが、
"2008年6月2日"のような形式の文字列は、DataOption1:=xlSortTextAsNumbersで数値としてみてないらしいぞ。
"2008/6/2"というような形式の文字列なら、きちんとシリアル値と解釈して並び替えるようだが。
VBAでは"2008年6月2日"のようなローカルな形式はサポートしてないんじゃない?

369 :y:2008/07/11(金) 19:54:57
>>368

「数値に見えるものはすべて数値として並べ替えを行う」オプションは、
2003以前のバージョンでも、普段のソートダイアログには出てきません。
セル書式が文字列になっているセルを含むセル範囲を基準に並べ替えを
行う場合に限り、「並べ替えの前に」ウィンドウが開き、その中にあります。

うちのはExcel2003ですが、上記の方法でうまく並べ替えできます。
2007では何かが変わってしまったのでしょうか...

"yyyy年m月d日"の形の文字列は、少なくとも2003のVBAでは解釈可能です。
たとえばDateValue("2008年6月2日")とすると、
正しく39601が返されます。
ひょっとして2007では、これもエラーになってしまいますか?
だとすればサポートされなくなったのかも...
職場のPCにExcel2007が入ったので、今度自分でも試してみます。

何にしても、Excel的にはシリアル値+書式指定にしておくのが
一番ですね。


370 :364:2008/07/11(金) 20:08:18
うーむ、2007ではセル書式が文字列になっててもそういうウィンドウは開かないみたいね。
それからMsgBox CLng(DateValue("2008年6月2日"))とすれば2007も39601が返るよ。

とにかく>>353のいうように"2008年6月2日"って形式だと、あのコードではうまくいかないね。
昔、記録マクロが動かないことってNumberFormatで確かあったなぁ。
今回も似たようなことじゃないかな?



371 :y:2008/07/11(金) 21:22:09
>>370
参考までに、Excel2003ではこうなります。
ttp://www2.uploda.org/uporg1536890.avi.html

>>349
2007の印刷プレビューについて、今日職場で試してみたら、2003以前とは
全然挙動が違うようですね。
2003以前ではプレビューを開くと必ず標準状態で開きましたが、
2007ではプレビュー画面を拡大状態で閉じると、次回表示したとき
拡大状態で開いてしまうようです。従って、お望みの動作は、残念ながら
SendKeysステートメントを使っても得られないようです。


372 :デフォルトの名無しさん:2008/07/12(土) 00:32:36
おれ、こういうの気持ち悪いので
いったんテンポラリバリアントで取得してタイプネーム確認する 特に日付

373 :364:2008/07/12(土) 07:59:20
>>371の動画はダウンローダー使ってるせいか見れなかったが、2007でもオプションで「ふりがなを使わない」にしたらやっと「数値に見えるものはすべて数値として並べ替えを行う」のウィンドウが出たよ。
aaa bbb
2008年6月3日 2
2008年6月30日 1
2008年6月28日 3

A列の書式が文字列のこのようなデータで記録マクロをとってみたが、下のような今まで全然見たこともないようなコードだった。
Sub Macro1()
' Macro1 Macro
Range("A1:B4").Select
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A2:A4"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A1:B4")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlStroke
.Apply
End With
End Sub
これはきちんと動くようだ。

374 :364:2008/07/12(土) 08:00:09
続き

そこで2003用の下のようなコードを書いて走らせてみたが、全然期待したようには動かんね。

Sub foo()
With Range("A1").CurrentRegion
.Sort Key1:=.Range("A1"), Order1:=xlDescending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
:=xlPinYin, DataOption1:=xlSortTextAsNumbers
End With
End Sub

>>353は2003で作ったマクロを2007で走らせたんじゃないの?

375 :364:2008/07/12(土) 08:09:14
上の「期待したようには動かん」は、期待したようには並ばないって意味だから。

376 :ちはる:2008/07/12(土) 18:44:39
regexpも良いけど、like演算子も状況によっては悪くないのよ!!!!
ぷんぷん!!!!!

Sub aho()
'3の倍数と3の付く行はアホになります。
Dim i
For i = 1 To 1000
If i Like "*3*" Then
Cells(i, 1).Value = "アホ"
ElseIf i Mod 3 = 0 Then
Cells(i, 1).Value = "アホ"
End If
Next
End Sub

もうジメジメして嫌になっちゃうわ。

377 :デフォルトの名無しさん:2008/07/13(日) 11:18:51
Shellの挙動がおかしくなった。最近Windows Updateしたあたりからだと思う。
例えば、
Shell "C:\Documents and Settings\Ore\デスクトップ\hoge.bat"
が、急に動かなくなった。

実行エラー5
プロシージャの呼び出し、または引数が不正です。だって。

7月のパッチをアンインストールしても直らない。
原因わかる人いますか?


378 :377:2008/07/13(日) 11:21:12
環境は、Xp + Excel 2003 です。

379 :デフォルトの名無しさん:2008/07/13(日) 14:19:42
>Shell "C:\Documents and Settings\Ore\デスクトップ\hoge.bat"
>が、急に動かなくなった。

うそこけ。動くわけなかろ

380 :デフォルトの名無しさん:2008/07/13(日) 15:23:02
> 379

そこは、動かない訳を書かないと。

Vista + Excel 2007で、
Shell "C:\Users\Ore\Desktop\hoge.bat"
は、動くね。


381 :デフォルトの名無しさん:2008/07/13(日) 16:42:04
WinXP(アップデート済) + Excel 2003 だと動かなかった。
C直下のものでも。exeファイルなら動くね。

382 :デフォルトの名無しさん:2008/07/13(日) 23:36:02
377です。

381さん、ご協力ありがとう。
ちなみに、hoge.batの中身は、何か書いてないとダメなようです。

例えば、
dir
pause
のような感じです。念のため。

あと、別のPC Xp Sp2 + Excel 2003 では、動くのを確認しました。
やっぱり、今月のパッチかな?


383 :381:2008/07/13(日) 23:43:52
ああ、確かに書けば動くね。

384 :デフォルトの名無しさん:2008/07/14(月) 17:37:05
質問です。1〜4の順にプログラムを進めたいと思っています。

1.メッセージボックス「セルを選んでください」。
2.メッセージボックスのOKボタンを押す。
3.シートに戻り、任意セルをクリックする。(セルが選ばれるまで先の処理に進まない)
4.選ばれたセルの情報を取得。

環境はExcel2000 WinXPです。

このような処理をしたいのですが、
どういう考え方で進めたらよいでしょうか?
よろしくお願いします。


385 :デフォルトの名無しさん:2008/07/14(月) 17:53:59
Sub test()

MsgBox "セルを選んでください"

End Sub

386 :デフォルトの名無しさん:2008/07/14(月) 18:01:01
>>384
結構厄介だと思うので、もっと楽にできるU/Iで作ってみてから挑戦するといいと思う。
当然ではあるが、>385では2番までしか実装されていない。

387 :384:2008/07/14(月) 18:09:53
>>385
書き方が悪くてすいません。でもちょっとワロタ
メッセージボックスを出した時だけ、直後で選ぶセルの情報を取得したいんです。

>>386
厄介ですか。
Worksheet.SelectionChange やAPIでなんとか出来ないかなあと思っていたんですけど・・


388 :って書くと、知らないのに書くなとか書かれるんだろうなぁw:2008/07/14(月) 18:11:43
>Worksheet.SelectionChange やAPIでなんとか出来ないかなあと思っていたんですけど・・
それが判っていて、厄介じゃないと思うなら自分でやってみてくれ。
説明するのも厄介だぞ。

389 :デフォルトの名無しさん:2008/07/14(月) 18:28:53
InputBoxメソッドで
Typeを8でどうさ?

390 :384:2008/07/14(月) 19:06:52
>>388
いえいえ。どうもありがとうございます。
知っているから厄介だと分かるのだと思います。
別の考え方や参考になる意見を聞けたらいいなあと思ってました。
説明も厄介であれば仕方ないです。

>>389
なんだかよさそうですね。
タイプ8にこんな機能があったとは・・
とりあえずそれでやってみます。

>>386さんの言うとおりU/I使ってあんまり欲張らないで
ちょっとずつやっていくほうがいいみたいですね。

みなさんホントどうもです。聞いてよかったです。





391 :デフォルトの名無しさん:2008/07/14(月) 19:13:25
>385もあながち悪くないと思った暑い夕暮れ

392 :y:2008/07/14(月) 22:03:21
>>384
SelectionChangeイベントを使う場合の考え方:
パブリック変数を用意し、イベント許可フラグとして用いる。
イベント発生時、イベントプロシージャの冒頭で
イベント許可フラグが立っているか否かを判定し、
プロシージャの内容を実行するか、何もせずにプロシージャを抜けるか
分岐させるようにしておく。
こうしておけば、普段はSelectionChangeイベントが発生しても
何もせずに終わるが、「セルを選んでください」表示後にフラグを
立てれば、次のSelectionChangeイベントでプロシージャの内容が
実行される。
ここでセルの情報を取得し、最後にフラグを元に戻しておく。
---------

ここまで書いておいて何ですが、
明らかに>>389のやり方のほうが優れています。

393 :デフォルトの名無しさん:2008/07/15(火) 00:05:38
1.メッセージボックス「セルを選びましたか?」
2.メッセージボックス「本当にいいんですか?」
3.メッセージボックス「いいんですね?」
1のところでなれたら使うボタンを追加しとくとか


394 :デフォルトの名無しさん:2008/07/15(火) 00:29:36
質問があります。
複数のワークシートにまたがった複数範囲の標準偏差を計算するため、最初はUnionでそれぞれの範囲のRangeを纏めて最後にWorksheetFunction.StDevで
計算するコードを書いてみたのですが、エラーが発生しました。
どうもUnionでは異なるワークシートのRangeは纏められないようで、何か別のいい方法は無いかと探しています。

例えば以下の例は、Sheet1の各列の中から、数値が10個以上ある列だけをUnionで纏めて標準偏差を求めるものです。

Dim myRange As Range, myMultipleRange As Range

Set myMultipleRange = Nothing

For Each myRange In Worksheets("Sheet1").Columns
If WorksheetFunction.Count(myRange) >= 10
If myMultipleRange Is Nothing Then
Set myMultipleRange = myRange
Else
Set myMultipleRange = Union(myMultipleRange, myRange)
End If
End If
Next myRange
If Not myMultipleRange Is Nothing Then
MsgBox WorksheetFunction.StDev(myMultipleRange)
End If

このような標準偏差の計算を、1つのワークシートの列だけでなく、ワークブック内のワークシート全体から、
10個以上数値がある列を調べて標準偏差を計算するような方法を探しています。
ただしワークシートの個数は決まっていません。
どのような方法を使えば上手く計算することが出来るのでしょうか?
環境はWindows XP、Excel2003です。
よろしくお願いします。

395 :デフォルトの名無しさん:2008/07/15(火) 08:48:16
>>394
作業シート作って(予め非表示で用意しておいても良いし、処理前に作成して処理後に削除しても良い)
そこに必要な値を書きだして計算する

またはワークシート関数を使わずに、普通に計算してもいいかもな
標準偏差関数のサンプルなんて腐るほどあるから、わざわざVBAから
ワークシート関数(WorksheetFunction)呼ばなくてもどうにでもなる

396 :デフォルトの名無しさん:2008/07/15(火) 12:45:01
ここで解説してくれる優しい方々は、やっぱりエクセル1級持ってるのかですな?

397 :デフォルトの名無しさん:2008/07/15(火) 12:56:23
そんなもの持ってるやついるの?

398 :384:2008/07/15(火) 13:02:18
>>392
レスどうもです。
「セルを選んでください」の表示前にあったセル位置の情報しか取得出来なくて、

>3.シートに戻り、任意セルをクリックする。(セルが選ばれるまで先の処理に進まない)

この3番のユーザーの入力待ちがどうしても出来ません。

>>393
どうもです。
連続した作業になるので、メッセージボックスは1度だけにしたいんです。




399 :デフォルトの名無しさん :2008/07/15(火) 15:42:46
VBAのソースコードをカラーで印刷する方法が判りません
印刷品質くらいしか選べなくてモノクロになっちゃいます
誰か教えてください・・・・

400 :デフォルトの名無しさん:2008/07/15(火) 17:07:33
print screenで画像保存してそれをカラー印刷すれば良いじゃん

401 :デフォルトの名無しさん:2008/07/15(火) 17:39:35
VBA初心者の者ですが、
(A:B)列のセルがゼロか空白ならば、
(1:50)の行が削除される構文をどなたか教えて頂けますか。

If Then Else ステートメントを使ってやるのでしょうか。
お願い致します。

402 :デフォルトの名無しさん:2008/07/15(火) 19:20:29
>>401
たとえばC51セルに =COUNTIF(A:B,"0")+COUNTIF(A:B,"") と式を打っておいて


Sub セルクリア()

If Range("C51") = 0 Then

Else

Range("1:1", "50:50").Clear

End If

End Sub

これで一応できるよ

403 :デフォルトの名無しさん:2008/07/15(火) 19:25:06
なんか間違えた
無かったことにしてW

404 :y:2008/07/15(火) 21:20:07
>>398

以下のコードを実装して、GetRangeを実行してみてください。
"セルを選んでください"が表示された直後に限り、
SelectionChangeイベントプロシージャの3行目以降が実行され、
さらにそこから"次の処理"プロシージャが呼ばれます。

■Module1
Public evFlag As Boolean
Public selectedRange As Range

Public Sub GetRange()
MsgBox "セルを選んでください"
evFlag = True
End Sub

Public Sub 次の処理()
MsgBox selectedRange.Address & "が選ばれました"
End Sub

■Sheet1
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If evFlag = False Then Exit Sub
Set selectedRange = Target
evFlag = False
Call 次の処理
End Sub

405 :デフォルトの名無しさん:2008/07/15(火) 21:25:23
>>398
メッセージの表示と入力を分ける必要はあるの?

これじゃダメなのか?
Sub セル選択()
Dim X As Range

On Error Resume Next
Set X = Application.InputBox(Prompt:="セルを選択して下さい", Title:="セルの選択", Type:=8)
On Error GoTo 0
If Not X Is Nothing Then
MsgBox "選択したセルは " & X.Address
Else
MsgBox "キャンセルしたよ"
End If
End Sub



406 :デフォルトの名無しさん:2008/07/15(火) 21:28:08
>>399
そもそもVBEのカラー定義は貧弱だから
その辺が強力かつ表示通りにカラー印刷出来るテキストエディタ使った方がいい

407 :y:2008/07/15(火) 21:31:21
>>398

念のためにまた書きますが、InputBoxメソッドを使った方が
はるかに簡単です。ほぼ同じことが以下の5行でできます。
しかも、他シートのRangeも取得可能です。

Public Sub GetRange2()
Dim selectedRange As Range
Set selectedRange = Application.InputBox("セルを選んでください", Type:=8)
MsgBox selectedRange.Address & "が選ばれました"
End Sub

>>404の利点は、セルが選ばれた瞬間に次の処理を発動させられる
点ぐらいです。(上の例はOKボタンを押す必要があります)


408 :y:2008/07/15(火) 21:32:34
>>405
あ、かぶっちゃった。

409 :デフォルトの名無しさん:2008/07/15(火) 21:34:37
Addressをデバッグ画面やmsgboxに表示させるときは
Address(0, 0)とした方が解りやすいぞ
習慣にしておこう

410 :401:2008/07/15(火) 21:47:30
>402
>403
ドンマイ w
でも、ありがとうございます。

どなたか、わかる方いらっしゃいますか?

411 :353:2008/07/15(火) 21:56:21
並び替えのことで質問したものですが
結局シリアル値での日付列を追加して無事処理できました。
いろいろとありがとうございますorz


412 :y:2008/07/15(火) 22:51:16
>>410

■初心者向け

Public Sub Del1()
Dim tmp As Range
For Each tmp In Range("A:B")
If tmp.Value <> "" Then
If tmp.Value <> 0 Then
Exit Sub
End If
End If
Next
Range("1:50").Delete
End Sub

413 :デフォルトの名無しさん:2008/07/15(火) 23:00:52
>>410
なんか質問がおかしいように思うよ。
>>412さんの構文の通り、セルに名前を付けてあるの?
名前を付けたセルの値が・・・って事なら構わないんだけど、
何か勘違いしてるかな。

A:B列の、どのセルを対象にしたいの?範囲は無し?
A列かB列の任意のセルに0か空欄があった場合、1行目から50行目までを削除するの?


414 :デフォルトの名無しさん:2008/07/15(火) 23:35:23
VB6で質問があるのですが
セルの値が分数で記述されているのを
隣のシートに小数点表記で表示させる方法ってありますか?

隣のシートには表示出来るのですが、小数点にならなくて

415 :y:2008/07/15(火) 23:59:33
>>410

■玄人向け(処理が速い)

Public Sub Del2()
Dim rg As Range, tmp As Range
With Range("A:B")
On Error GoTo err1
Set rg = .SpecialCells(xlCellTypeFormulas)
For Each tmp In rg
If tmp <> 0 Then Exit Sub
Next
err1:
On Error GoTo 0
On Error GoTo err2
Set rg = .SpecialCells(xlCellTypeConstants)
For Each tmp In rg
If tmp <> 0 Then Exit Sub
Next
err2:
Range("1:50").Delete
End With
End Sub
--------
>>413
たぶん>>410さんは、A:B列の「すべての」セルが0または""なら
1:50行を削除したい、という意図だろうと受け取っています。
ちなみに>>412では、名前は使っていないつもりですが、
どの部分のことですか?

416 :y:2008/07/16(水) 00:12:24
>>414

小数点表記させたいセルの書式を"標準"または"数値"にしてください。
"数値"にした場合は、小数点以下何桁まで表示させるかを指定してください。

VBAで処理したい場合は、NumberFormatプロパティで操作できます。
それをキーワードに検索してみてください。

417 :デフォルトの名無しさん:2008/07/16(水) 00:39:04
>>410
WorksheetFunctionを使った場合もどうぞ

Sub 削除()
With Application.WorksheetFunction
If (.CountIf(Range("A1:B50"), 0) <> 0) Or (.CountIf(Range("A1:B50"), "") <> 0) Then
Range("1:50").Delete
End If
End With
End Sub

だけど範囲がAB列全部てどうなのさww
いや、AB列全部に0もしくは空白が無いならいいけどさ

End(xlUp)とかを使ってデータの最終行を取得するとかをした方が
いいんじゃない?

418 :デフォルトの名無しさん:2008/07/16(水) 00:57:59
もう1つFindを使った場合もどうぞ

Sub 削除2()
Dim X(1) As Variant
With Range("A1:B50")
Set X(0) = .Find(0)
Set X(1) = .Find("")
If Not (X(0) Is Nothing) Or Not (X(1) Is Nothing) Then
Range("1:50").Delete
End If
End With
End Sub

あと、テストするのに範囲をA1:B50に指定してるから

419 :デフォルトの名無しさん:2008/07/16(水) 01:31:40
>>401

念のため補足しておくと、

>>412, >>415は、範囲内のすべてのセルの値が(空白または0)なら削除を行う処理
>>417-418は、範囲内に(空白または0)のセルが1個でも含まれていたら削除を行う処理

をアドバイスしている。
これは>>410の質問の仕方が曖昧だから。

420 :y:2008/07/16(水) 02:43:27
>>394

StDev関数は、Rangeオブジェクトだけでなく、配列変数も引数として
受け取ることができます。次のコードを試してみてください。

Sub t()
Dim args As Variant
args = Array(1, 2, 3, 4, 5)
Debug.Print WorksheetFunction.StDev(args)
End Sub

つまり、各シートに散らばっている数値を、いったん
配列変数にまとめ、配列ごとStDev関数に渡すやり方が可能です。
(Unionでやろうとしたことと考え方は同じです)

421 :デフォルトの名無しさん:2008/07/16(水) 08:27:19
確かに、慣れてない奴にウェブで調べさせた怪しげな標準偏差関数を自作させるよりは、
>420の方が余程まともだな。

422 :410:2008/07/16(水) 13:36:35
>412,415,417,418

丁寧にありがとうございます。

すみません説明不足でした。
A列かB列の任意のセルに0か空欄があった場合、
【0か空欄がある行だけ抜き出して削除する】処理がしたいのです。

412,415,417,418を試しにやってみましたが、
1〜50行全て消えてしまったので、これだとちょっとマズいんです。(笑)

誠にお手数かけますが、ご教授頂けますでしょうか
お願い致します。



423 :デフォルトの名無しさん:2008/07/16(水) 14:04:58
>>422
少しは自分で考えよう
>>1★5


>>その他
踊らされてなんでもホイホイ答えずに
多少は質問者にも頭使わせよう

424 :デフォルトの名無しさん:2008/07/16(水) 14:12:14
Findのヘルプを読んでみ

425 :デフォルトの名無しさん:2008/07/16(水) 14:14:47
>>422

えーーーー

>VBA初心者の者ですが、
>(A:B)列のセルがゼロか空白ならば、
>(1:50)の行が削除される構文をどなたか教えて頂けますか。

どう読み取っても50行目まで全部削除したい主旨じゃん・・
ちゃんと質問してくれよ

まあ答え解らないけどwwwwwww


426 :デフォルトの名無しさん:2008/07/16(水) 14:21:45
VBAの前に日本語だな

427 :デフォルトの名無しさん:2008/07/16(水) 14:59:51
Sub sakujo()
Dim i
Dim j
Dim q
j = Cells(Rows.Count, 1).End(xlUp).Row
i = 1
Do Until q > j
If Cells(i, 1).Value = "" Or Cells(i, 1).Value = "0" Or Cells(i, 2).Value = "" Or Cells(i, 2).Value = "0" Then
Rows(i).Select
Selection.Delete Shift:=xlToLeft
q = q + 1
Else
q = q + 1
i = i + 1
End If
Loop

あえて解説はしない。

428 :デフォルトの名無しさん:2008/07/16(水) 15:00:53
Sub hoge()
Dim i
Dim j
Dim q
j = Cells(Rows.Count, 1).End(xlUp).Row
i = 1
Do Until q > j
If Cells(i, 1).Value = "" Or Cells(i, 1).Value = "0" Or Cells(i, 2).Value = "" Or Cells(i, 2).Value = "0" Then
Rows(i).Delete
q = q + 1
Else
q = q + 1
i = i + 1
End If
Loop
End Sub

で・・・。何やっとんだワシ・・・。

429 :デフォルトの名無しさん:2008/07/16(水) 16:16:15
>>428
うまくいってないよ

430 :410:2008/07/16(水) 16:22:47
うわ・・・皆様本当にご迷惑おかけして
申し訳ないです。

>427・428
ありがとうございます。
でも、やってみましたが、削除できてないっす。

難しいですね・・・

431 :デフォルトの名無しさん:2008/07/16(水) 16:30:34
>>410
>412,415,417,418を試しにやってみましたが、
>1〜50行全て消えてしまったので、これだとちょっとマズいんです。(笑)

当たり前でしょ、最初の質問がそういう条件だったんだから

取りあえず、Findを使った場合の処理

Sub 削除3a()
Call 削除3b(0)
Call 削除3b("")
End Sub

Sub 削除3b(FD As Variant)
Dim X As Variant, XAddr As Variant
Dim XS As String

With Range("A1:B50")
Do
Set X = .Find(What:=FD, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, MatchByte:=False)
If Not X Is Nothing Then
Range(X.Row & ":" & X.Row).Delete
End If
Loop Until X Is Nothing
End With
End Sub


432 :410:2008/07/16(水) 16:43:07
>431
ありがとうございます。
空白だけの行は削除されました!
でも0が入ったセルの行は削除されませんでした。


433 :428:2008/07/16(水) 16:43:13
あれ?動かないですか?
A列とB列を判定してhitしたらその行消してるだけなんだけど。

434 :デフォルトの名無しさん:2008/07/16(水) 16:45:07
教えてください。エクセル2007でV-nasCADの画像を貼り付けて印刷したら
印刷があれるのですが、どうしたらいいでしょうか?
2002の時はきれいにでていたのですが・
だれか教えてください。

435 :431:2008/07/16(水) 16:52:21
>>410
指定範囲はあっている?
俺の書いたコードはA1:B50までの範囲しか対象にしていないよ

もしくは引数の指定が正しくできてる?

436 :410:2008/07/16(水) 17:08:12
合ってますが、やはり0が入ったセルの行が削除されません。

Range(X.Row & ":" & X.Row).Delete

この部分に"0"を入れなければならないのでは?

437 :デフォルトの名無しさん:2008/07/16(水) 17:14:08
じゃあ入れて試してみろやボケ

438 :431:2008/07/16(水) 17:22:36
>>410

取りあえずコードの説明しとくよ

Sub 削除3a()
' 削除3bプロシージャの呼び出し
Call 削除3b(0) ' ←セルの値0を削除(引数として0をセット)
Call 削除3b("") ' ←空白セルを削除(引数として""(空白)をセット)
End Sub

Sub 削除3b(FD As Variant)
Dim X As Variant, XAddr As Variant
Dim XS As String

With Range("A1:B50") ' セル範囲"A1:B50"を指定
Do
' ↓引数FDに指定された値のあるセルを検索
' セルがあった場合はそのRangeオブジェクトを変数Xにセット
Set X = .Find(What:=FD, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, MatchByte:=False)

' ↓Rangeオブジェクトの取得がされていない場合は処理をしない
If Not X Is Nothing Then
'指定されたセルの行番号のセルを削除
Range(X.Row & ":" & X.Row).Delete
End If
Loop Until X Is Nothing 'Rangeオブジェクトの取得がされていない場合はLoopを抜ける
End With
End Sub


439 :デフォルトの名無しさん:2008/07/16(水) 17:33:03
Sub test()

Range(401).Delete

End Sub

440 :デフォルトの名無しさん:2008/07/16(水) 18:47:10
>>401
今いちど、何をしたいのかを日本語で誰にでもわかるように書いてみれ。


441 :デフォルトの名無しさん:2008/07/16(水) 18:54:42
>>428
"0"だと文字列。数値の0の判定を追加しないといかん。

442 :デフォルトの名無しさん:2008/07/16(水) 19:54:03
Cells(a,b)が、とあるRange(Unionであっちこっちくっつけてる)の中に含まれているかどうかを返す関数ってあります?

443 :デフォルトの名無しさん:2008/07/16(水) 20:58:59
>>442
なかったらこれ使えるかな?

Function included(ByVal maybeSubset As Range, ByVal maybeSuperset As Range) As Boolean
included = maybeSubset.Count = Application.Intersect(maybeSubset, maybeSuperset).Count
End Function

444 :y:2008/07/16(水) 21:04:40
>>422

【0か空欄がある行だけ抜き出して削除する】処理、ということであれば、
AutoFilterが便利です。

Sub Del3()
Range("1:1").Insert
With Range("A1:B51")
.AutoFilter field:=1, Criteria1:="=", Operator:=xlOr, Criteria2:="0"
Range("A2:B51").SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter field:=2, Criteria1:="=", Operator:=xlOr, Criteria2:="0"
Range("A2:B51").SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
ActiveSheet.AutoFilterMode = False
Range("1:1").Delete
End Sub

0または空白の行だけを表示させ、表示されている行だけを削除する、
という処理を、A列とB列に順番に行っています。
1行目に新しい行を挿入し、最後に消しているのは、AutoFilterを使うために
見出し行が必要だからです。


>>442
Intersect関数を使ってみてください。
複数のセル範囲の共有範囲を返す関数です。
共有範囲が返らなかったら、「含まれていない」と判断できます。

445 :y:2008/07/16(水) 21:10:09
あ、既に>>443で答えが出てましたね。


446 :442:2008/07/16(水) 21:13:48
>>443,444
ありがとうございます、無事にできました。

447 :デフォルトの名無しさん:2008/07/16(水) 21:43:24


   うぜーよ




448 :デフォルトの名無しさん:2008/07/17(木) 00:25:04
何がだ

449 :394:2008/07/17(木) 02:38:11
レス頂きありがとうございます。

>>395
StDev無しで普通に計算する方法も考えましたが、もっと効率的な方法はないものかと思い質問させて頂きました。

>>420
配列が使えるというのは初めて知りました。
その方法で試してみたいと思います。

450 :デフォルトの名無しさん:2008/07/17(木) 10:23:40
>>398
亀だがこんなのもできる一応

Public waiting_selection_change As Byte
Function user_selected_range() As Range
waiting_selection_change = 1
MsgBox "セルを選択して下さい"
While waiting_selection_change = 1
DoEvents
Wend
Set user_selected_range = Selection
End Function

Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)
If waiting_selection_change = 1 Then waiting_selection_change = 0
End Sub

451 :デフォルトの名無しさん:2008/07/17(木) 11:45:20
生徒の試験の点数を降順(100、97、90・・・)に並べてある
A列の隣(B列)に1、2、3と順位をつけて、尚且つ、
A列の空白になっているセルには順位をつけないようにするには、
どうしたらいいでしょうか。ご教授お願い致します。

452 :451:2008/07/17(木) 12:07:20
すみません

>A列の空白になっているセルには順位をつけないようにする
→B列のセルを空白のままにするには

でお願い致します。

453 :デフォルトの名無しさん:2008/07/17(木) 12:56:37
もう1つ列を作って呼び出さないようにする。

454 :デフォルトの名無しさん:2008/07/17(木) 14:11:48
Sub junni()
Dim i
Dim j
j = 1
For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
If Cells(i, 1) <> "" Then
Cells(i, 2) = j
j = j + 1
End If
Next i
End Sub


455 :デフォルトの名無しさん:2008/07/17(木) 17:38:27
検索についてお聞きしたいのですが、
シート全体を対象に検索する場合はCellsで可能なんですが、
特定のセル範囲を検索する場合ってどうやればよいでしょうか?

例えばA1:C10の範囲内のセルだけ"パソコン"という文字列を検索するにはどうすればよいでしょうか。

456 :デフォルトの名無しさん:2008/07/17(木) 19:00:44
cellsは全セル対象でおk。

指定範囲は、
Range("A1:C10").Find(What:="パソコン").Activate
こんな感じ。
マッチした後の処理が書いてないから、マッチしたセルをactive。

457 :デフォルトの名無しさん:2008/07/17(木) 19:27:38
>>456
なるほど。
What;= が必用だったのか・・
ありがとう。

458 :デフォルトの名無しさん:2008/07/17(木) 23:24:35
>>457
セミコロン(;)じゃなくて、コロン(:)だよ

あと、「What:=」見たいに使うのを名前付き引数といって
指定()内に記述する順番がばらばらでも大丈夫な引数指定の事

省略した場合はFindの場合(What:=, LookIn:=, LookAt:= …)の順に引数を指定したとみなされる


459 :デフォルトの名無しさん:2008/07/18(金) 00:30:09
かなりなスレ違いお許し下さい

過去の株価をVBAで検証したいのですがスキル不足です。
検証の内容は、ごく単純なもので恐らく数十分ほどで組めるのではないかと思われます。
(検証条件=システムは、恥ずかしい位、幼稚なものです。期待なさらないで下さい。
特別な秘密など有したものではありません・・)

どなたか有償でVBAを組んで頂けませんでしょうか。
報酬は、先払い3000円・完成後3000円の合計6000円を考えています。
指定口座に迅速にお振込み致します。

二か月分の株価を載せたエクセルデータと
検証条件を説明したテキストファイルを作りました。
これをメールでお送りします。
請け負って頂けるか否か、報酬は上記金額で良いか
とりあえずお見積もりして頂ける方メール下さい。
どうぞ宜しくお願い致します。

460 :デフォルトの名無しさん:2008/07/18(金) 01:04:58
>>459
口座無いからタダでやりたい

461 :459:2008/07/18(金) 01:10:20
>>460
書留ででもお送りしますよ^^
そうゆうのもお嫌でしたら無償でもいいですがw
よかったらメール下さい

462 :デフォルトの名無しさん:2008/07/18(金) 01:13:14
商品コード 数量 商品名 単価 合計
このような列の集まりで、
商品行が増えていくシートで、発注表を作っています。

数量は普段空白で、注文するときに数量を入れて、
数量がない行は削除(上にシフト)して、プリントアウトしています。
最終的に「数量が空白」を全部消してからプリントになります。

で、これをマクロにすると
数量(一番初めの商品は3行目なのでB3セル)が書いていなければ行削除、
数量が書いてあった場合は何もせずに下の行へ。

で、最後に識別文字の「★」であれば、終了ということをやりたいです。
マクロで観てみると

Rows("3:3").Select
Selection.Delete Shift:=xlUp

このように出ました。
3行目を削除して上にシフトしています。

463 :462 :2008/07/18(金) 01:14:20
if(現在のセルが★が入っていなければ)
{
  if(現在のセルが空でなければ)
  {
   その行を選択して
   削除(上にシフト)
  }else
  セルを下に移動
}
 プリントアウト

 こんな感じで脳内ではできたのですが、コード化は無理ぽですorz
 どう書けばいいでしょうか?

464 :459:2008/07/18(金) 01:23:30
>>461
メール送りました。
とりあえず内容見て考えさせてください。

465 :デフォルトの名無しさん:2008/07/18(金) 01:26:36
>>462
このスレの410宛てのレスを読め

大体似たような処理で出来る

466 :デフォルトの名無しさん:2008/07/18(金) 01:33:50
>>463
Sub hoge()
Dim startCell As Range
Set startCell = [C4] ' 商品コードの値が始まるセル
Dim i%
While startCell.Offset(i) <> "★"
With startCell.Offset(i)
If .Offset(, 1) = "" Then
.EntireRow.Delete
Else
i = i + 1
End If
End With
Wend
End Sub


467 :459:2008/07/18(金) 01:36:30
>>464
ありがとうございました
本メールから今、送信しました
ご検討宜しくお願い致します

468 :459:2008/07/18(金) 01:37:56
>>467
了解です^o^
今みてます

469 :デフォルトの名無しさん:2008/07/18(金) 09:05:13
香ばしいこと行われているようですねw

470 :デフォルトの名無しさん:2008/07/18(金) 16:09:08
worksheetsを追加した際に
そのシートにWorksheet_Activate()
も追加したいのですが、どのように指定すればできるのでしょうか?

471 :デフォルトの名無しさん:2008/07/18(金) 17:05:33
普通にやればいいじゃん

472 :470:2008/07/18(金) 17:21:42

worksheets.add after:=activesheet
で新しいシートを追加するマクロがあるのですが、worksheets.????みたいな感じでなにかできる方法があるのでしょうか?
マクロで追加したシートにマクロを記述する関数などありましたら教えていただきたいです。

473 :デフォルトの名無しさん:2008/07/18(金) 17:33:49
だから、「VBAを使ってVBAコードを記述する」方法を普通にやればいいだけだってば
検索すればいくらでも情報は出てくる

474 :470:2008/07/18(金) 18:28:56
ありがとうございます。
検索したら
With ThisWorkbook.VBProject.VBComponents.Item("Sheet2").CodeModule
.InsertLines 1, "書きたいコード"
End With
でできるみたいですね。
ありがとうございます。

475 :デフォルトの名無しさん:2008/07/18(金) 20:05:09
本当にやりたい目的と、今とろうとしている手段が乖離している気がするが、まあいいや

476 :デフォルトの名無しさん:2008/07/18(金) 20:08:16
>>472

hoge = activesheet.index
worksheets.add after:=activesheet
sheets(hoge+1).activate

じゃダメ?

477 :デフォルトの名無しさん:2008/07/18(金) 20:21:01
>>476
アクティベイトしたいんじゃなくて、ハンドラを入れたいんでしょ。

478 :デフォルトの名無しさん:2008/07/18(金) 20:54:15
>>470
普通に標準モジュールにコードを書けばいいんじゃねーの?

イベントハンドラが使うならクラスモジュールを使えばいいし

479 :デフォルトの名無しさん:2008/07/18(金) 23:51:10
ExcelVBAを扱うExcelVBAコードはないのか!

480 :463:2008/07/19(土) 02:28:06
>>466
| Dim startCell As Range
| Set startCell = [C4] ' 商品コードの値が始まるセル

発注書:日付
商品コード 数量 商品名 単価 合計
001      1   hoge  3,000 3,000
002         hoge  1,500 
003      1   hoge  2,000 2,000
004         hoge  4,000 
        ★
こんな感じなので、商品コードはA3になります。
ここをA3に変更して実行したところループになりました。
今回は★は[B7]ですね。

| Dim i%
ここの「%」の意味がわかりませんでした。
先述のAs Rangeはオブジェクトということはわかりました。

| While startCell.Offset(i) <> "★"
 [A3]のi行下が★でなければということで、★の位置をA7にしたらループが止まりました。

| With startCell.Offset(i)
| If .Offset(, 1) = "" Then
 i行オフセットした右隣が""の場合

| .EntireRow.Delete
 その行を削除

| Wend
While ... Wendという使い方、御教示ありがとうございます。
 とても勉強になりました。

481 :463:2008/07/19(土) 02:33:17
すいません、どうしても気になることが・・

| Dim i%
| While startCell.Offset(i) <> "★"
| With startCell.Offset(i)

特に i = 1
と変数に入れていないのですが、なぜiが1を入れたような挙動を
取るのでしょうか?
i% に何かしらそういう意味があるのでしょうか?

482 :463:2008/07/19(土) 02:47:44
>>466
startCell の数量[B3]に数値があれば、完璧に動作をするのですが、
この数量[B3]に数値がなければ、
・startCell行の数量が空(★ではない)ので、行を削除
してWendからwhile行を実行しようとした瞬間に

実行時エラー:424
オブジェクトが必要です
と出てストップします。

While startCell.Offset(i) <> "★"
ここで止まってしまうのですが、1回目は行削除できるのに、
なぜか2回目の処理で止まってしまうのが、よくわかりません・・・。

483 :デフォルトの名無しさん:2008/07/19(土) 03:16:19
>>463

>Dim i% ← これは、変数iを整数型で宣言している
%が整数型の型宣言文字

>特に i = 1
>と変数に入れていないのですが、なぜiが1を入れたような挙動を
>取るのでしょうか?

これについては
↓のIfで空白なら行を削除、空白で無いなら i に+1している
If .Offset(, 1) = "" Then
 .EntireRow.Delete
Else
 i = i + 1
End If

>実行時エラー:424
>オブジェクトが必要です
>と出てストップします。

これについては
Set startCell = [C4] でstartCellにRangeオブジェクトをセットしているのに
そのセルを削除してしまったので、セットしたRangeオブジェクトがねーよwwとExcelが言ってるだけ

基本的に削除するセルを基準にしちゃだめだろ




484 :デフォルトの名無しさん:2008/07/19(土) 03:55:10
>>463
あとWhile ... Wendという使い方もあるけど
普通はDo〜Loopを使うよ

Do〜Loopを使う場合はこんな感じ

Sub ★まで削除()
 Dim TCell As Range
 Dim iX As Integer

 Set TCell = Range("B2") ' ★のある列のタイトル部分(商品コードとか数量と書いてあるセル)
 iX = 1
 Do Until TCell.Offset(iX, 0).Value = "★"
  With TCell.Offset(iX, 0)
   If .Value = "" Then
    .EntireRow.Delete xlShiftUp
   Else
    iX = iX + 1
   End If
  End With
 Loop
End Sub

485 :デフォルトの名無しさん:2008/07/19(土) 04:05:48
Do...LoopがあるからWhile ... Wendなんていらね、使った事もない。
While ... Wendなんて使うとコードが汚れるとさえ思える。

486 :デフォルトの名無しさん:2008/07/19(土) 09:42:09
へー

487 :y:2008/07/19(土) 10:27:10
>>484
元の質問とは関係ないですが、コードがインデント付きで表示されて
いるのでびっくりしました。しかも、VBAEditorが全角スペースを自動的に
半角スペースに変換してくれることを初めて知りました。
>>484をそのまま貼り付けるとエラーになると思い込んでた)

これはVBAEditorの仕様でしょうか?
それとも「全角空白は半角に変換する」みたいなオプションが
どこかにあるのですか?



488 :デフォルトの名無しさん:2008/07/19(土) 10:51:13
VBAEditorではなくVBEditor(Visual Basic Editor/VBE)ですよ
例えEditする対象がVBAでもね

で、これはオプションではなく固定仕様、VBEのと言うよりはMS製IDEの仕様だけどな
まあMS製以外でもこの機能を有するIDEはあるし
テキストエディタでもマクロや正規表現定型置換を用意しておけば一発だけど

因みに、一応半角スペースでインデントすることも出来ますよ

Do Until TCell.Offset(iX, 0).Value = "★"
With TCell.Offset(iX, 0)

ブラウザに因っては正しく表示&コピー出来ない場合もあるけど

489 :デフォルトの名無しさん:2008/07/19(土) 10:54:26
因みに↑はJaneとかの専ブラ向けね
確かIE向けは↓かな

    Do Until TCell.Offset(iX, 0).Value = "★"
        With TCell.Offset(iX, 0)

490 :y:2008/07/19(土) 11:19:34
>>488 ありがとうございます。私も試しに...

Sub test()
 With Range(Range("a2"), Range("b:b").Find("★").Offset(-1)).EntireRow
  .AutoFilter field:=2, Criteria1:="="
  .Offset(1).SpecialCells(xlCellTypeVisible).Delete
  .AutoFilter
 End With
End Sub

(コードは>>463の別解。★の行も含めて消えますが)

491 :デフォルトの名無しさん:2008/07/19(土) 11:21:48
うぜーよ

492 :デフォルトの名無しさん:2008/07/19(土) 12:03:41
>>485
他の言語からやってきたものからすると、
While ~ Wendの方がとっつきやすいんだよ。
単なるキーワードの違いだがな。
ただ、While ~ Wendだとループの脱出が…

493 :485:2008/07/19(土) 18:43:46
やっぱりそうだよな、他の言語やってるとそうなんだけどね。
でもVBではDo...Loopに限るよ、Do...Loopの仕様は反復制御として完璧だからね。

494 :デフォルトの名無しさん:2008/07/19(土) 22:06:59
uze-yo

495 :デフォルトの名無しさん:2008/07/19(土) 22:27:37
心の狭い子…

496 :デフォルトの名無しさん:2008/07/19(土) 23:01:26
こんばんは。VBE初心者のものです。

講義の宿題で7×7の魔方陣をVBEで解いてこいといわれました。
しかしながら自分のスキルでは動にもなりませんでした。

自分はIFやDim等までしか習っていませんがそれで解ける方法があったら
誰か助けてください。




497 :デフォルトの名無しさん:2008/07/19(土) 23:06:32
ループで全通り回せばいいだけじゃん

498 :デフォルトの名無しさん:2008/07/19(土) 23:18:58
・中央は25
・1列の合計は(1+25)*25/5で130


499 :デフォルトの名無しさん:2008/07/19(土) 23:28:59
>>498
???
25x7=175

500 :デフォルトの名無しさん:2008/07/19(土) 23:37:58
ちがったか
1から25の合計は(1+25)*25/2=325
1列の合計はこれを5で割るから65だな

501 :デフォルトの名無しさん:2008/07/20(日) 00:23:45
最上段中央に1を配置したら、右上に移動しながら2,3,4と次の数値をと入れていき、7の倍数時は右上ではなく下へ移動

上下、左右がループしてるとして(つまり1行目の上は7行目、7列目の右は1列目)この処理を続ければあっという間に完成

奇数の場合は上記の法則が使えるので超簡単
因みに7*7の場合は(1+7^2)/2*7で175が1列の合計
コードはForと算術演算(数値計算)が使えれば条件分岐(IF)すら要らない簡素なもの
小学生あたりにはオススメの問題だ

502 :デフォルトの名無しさん:2008/07/20(日) 00:26:27
>>501
複数の解(回転・鏡像を除く)が存在する場合も無視?

503 :デフォルトの名無しさん:2008/07/20(日) 00:30:01
無視って何を?

504 :デフォルトの名無しさん:2008/07/20(日) 02:27:42
どうやったら条件分岐使わずに書けるのかわからん
その小学生にお勧めのコードをお教えくださいませ

505 :デフォルトの名無しさん:2008/07/20(日) 02:30:27
あと、開始座標がどこでも結果同じだろ。
マ板とは思えんなここ

506 :デフォルトの名無しさん:2008/07/20(日) 05:45:41
別に501が唯一の解法だなんて書いてないし、
解法の一つとしては間違ってないわけだが、この子は何が気に入らないんだろう?
何か勘違いしてるのかな?

507 :デフォルトの名無しさん:2008/07/20(日) 06:45:52
ちょっと書くだけで過剰反応するバカがいるから面白がってるだけ

508 :デフォルトの名無しさん:2008/07/20(日) 08:30:49
>>501にからんでるやつ頭悪そう。
魔方陣には特殊な解があるぞという回答に対して他の解は無視かよだなんてスジ違いのイチャモン。
頭が悪いんだろうな。

509 :デフォルトの名無しさん:2008/07/20(日) 08:35:53
ごめん。魔方陣って何?
面白そうなのに全然話に参加できないんだけど。

って人が多いと思う・・・俺含め。(俺だけ?)

510 :デフォルトの名無しさん:2008/07/20(日) 08:39:54
魔方陣を知らない人は少ないと思う。
君は少数派。

511 :デフォルトの名無しさん:2008/07/20(日) 09:22:18
ググれカス

512 :デフォルトの名無しさん:2008/07/20(日) 10:33:05
寧ろwikiれ

513 :デフォルトの名無しさん:2008/07/20(日) 11:00:50
>>505
マ板じゃないからな・・・

514 :y:2008/07/20(日) 11:05:25
>>509ではないですが、私も魔方陣のことはあまり知らなかったので、
性質を調べてマクロを組んでみました。非常に面白いです。
どうせやるなら、n * n の魔方陣のすべての解を列挙できるように
しようと思い、基本的に>>497の総当り方式でやってますが、かなり浅はかでした。

3*3は1秒ぐらいですべての解(8通りでOK?)が求まるのですが、
4*4は今の調子だと4〜5時間はかかりそうです(現在バックグラウンドで計算中)。
あるサイトによると6*6で約1800京通りあるらしく、7*7のすべての解など
到底無理なんだと理解。自己満足な知識がまた1つ増えました。

全然アドバイスになっていませんが、>>496の宿題で求められているのは、
要するに>>501で紹介されているようなオーソドックスな解法をVBAで
シミュレーションせよ、ということなんでしょうね。

515 :デフォルトの名無しさん:2008/07/20(日) 11:05:28
魔法も使えないって
おまえら30年間何してきたんだよ

516 :デフォルトの名無しさん:2008/07/20(日) 11:33:30
魔 *方* 陣

517 :y:2008/07/20(日) 11:41:12
話題ついでに、質問させてください。

>>514で触れた「総当り方式」を実現するために、1 から n^2 までのn^2個の配列に、
すべての順列組み合わせを生成する再帰プロシージャを書きました。

これまで再帰処理はめったに使う機会がなかったので、今ちょうど気になっているのですが、
VBAの仕様としては、関数の多重呼び出しはどのくらいの深さまで許容されているのでしょうか。
MSDNには「多重呼び出しをやりすぎるとStackOverflowExceptionになりますよ」とあるのですが、
それ以上の情報は見つけられませんでした。(環境依存でしょうか?)


518 :y:2008/07/20(日) 11:44:32
(修正します)
「1 から n^2 までのn^2個の配列に、」
   ↓
「1 から n^2 までのn^2個の配列について、」


519 :デフォルトの名無しさん:2008/07/20(日) 13:41:30
試してみた(Excel2000)

Function test(i)
test = test(i + 1)
End Function

test 1でエラーが出たところでiは4227だったよ
ちなみに
Function test(i As Integer) As Integer
とすると6453

Function test(i, j)
test = test(i + 1, j + 1)
End Function
では3453

深さの問題じゃないね

520 :デフォルトの名無しさん:2008/07/20(日) 13:52:31
講釈ばっかで回答が一つも無い件

521 :デフォルトの名無しさん:2008/07/20(日) 14:11:33
Sub 魔方陣()

range("A1") = "7×7の魔方陣"

End Sub


できたよ〜

522 :デフォルトの名無しさん:2008/07/20(日) 15:50:04
Wikipediaの記述どおりつくってみたつもりだが… 5,9,13…がうまくいかない
http://ja.wikipedia.org/wiki/%E9%AD%94%E6%96%B9%E9%99%A3
Const size = 15
Sub 魔方陣()
Cells.Clear
If size Mod 2 = 0 Then End
Dim i%, x%, y%
x = size / 2 + 1
y = 1
For i = 1 To size * size
Cells(y, x) = i
y = y - 1
x = x + 1
補正 x, y, i
Next i
End Sub

Sub 補正(ByRef x%, ByRef y%, ByVal i%)
y = (size + y) Mod size
x = (size + x) Mod size
If y = 0 Then y = size
If x = 0 Then x = size
If Cells(y, x) <> "" Then
y = y + 2
x = x - 1
If i < size * size Then
補正 x, y, i
End If
End If
End Sub

523 :デフォルトの名無しさん:2008/07/20(日) 16:05:58
よくわからんが
size / 2 + 1

524 :デフォルトの名無しさん:2008/07/20(日) 16:07:13
を、
(size + 1) / 2
にするだけなんじゃ?

525 :522:2008/07/20(日) 16:11:11
>>523-524
わwそんな罠があるとはw削られるもんだと思ってたw
ありがとう

526 :デフォルトの名無しさん:2008/07/20(日) 16:23:12
それが原因なら5,9,13だけでなく3,7、11もうまくいかんだろ

527 :522:2008/07/20(日) 16:27:35
>>526
うまくいくみたい
3 / 2 + 1 => 2
5 / 2 + 1 => 4
7 / 2 + 1 => 4
9 / 2 + 1 => 6
11 / 2 + 1 => 6
13 / 2 + 1 => 8
15 / 2 + 1 => 8
17 / 2 + 1 => 10
19 / 2 + 1 => 10
21 / 2 + 1 => 12
23 / 2 + 1 => 12
25 / 2 + 1 => 14

528 :デフォルトの名無しさん:2008/07/20(日) 16:35:07
所謂ISO丸めだね。小数点以下一桁を丸める場合、その桁が5のときは偶数になるように丸める。
四捨五入とは違うから要注意だ。

529 :デフォルトの名無しさん:2008/07/20(日) 17:39:48
>>517
nestingは10じゃなかったっけ。

530 :デフォルトの名無しさん:2008/07/20(日) 18:13:01
ま、>>496はマルチだしな


531 :デフォルトの名無しさん:2008/07/21(月) 14:00:09
すみません、よくわからないので教えてください(excel2003)

1つのセルの中にALT+Enterで改行を入れ、複数項目を入れた場合
項目1つ1つを取り出すにはどうしたらよいのでしょうか?

tmp = Split(ActiveSheet.Range("A1").Value, "\n")
For i = 0 To UBound(tmp)
MsgBox tmp(i)
Next i

というようなコードを書いたのですが、すべて取得してしまいます
\nを\r、\r\nに変えても駄目でした

532 :デフォルトの名無しさん:2008/07/21(月) 14:20:45
そりゃそうだ
そのコードだと"\n"って文字で分割してるのであって改行コードで分割してるわけじゃないからな
VB、VBAの改行は、組込定数のvbCr、vbLf、vbCrLf、vbNewLineやChr(13)、Chr(10)であって
断じて\n、\r、\r\nでは無い

勝手に\n、\r、\r\nが使えることにするな
MsgBoxやDebug.Printで"a\r\nb"でも出力してみればわかることだろ
なんで最低限の確認も出来ないかなぁ?

ただコードを書くだけなら小学生でも出来るが、問題が起きたときに最低限のデバッグが出来ないと
VBA使えるとはとても言えないぞ

533 :デフォルトの名無しさん:2008/07/21(月) 14:35:02
>VBA使えるとはとても言えないぞ
VBA使えなくてもお前ら使えばいいだけだしなw

534 :デフォルトの名無しさん:2008/07/21(月) 14:41:34
>>531
regexpを使うと良いよ。正規表現。
パターンは ".*?\n" で行けるかな。

executeでコレクションに格納してから for each in で項目引っこ抜いても良いし、
submatchで引っこ抜いても行けると思うよ。


535 :デフォルトの名無しさん:2008/07/21(月) 14:42:25
セル内改行が \n で取得出来るか、ちょっと試してくるね。

536 :デフォルトの名無しさん:2008/07/21(月) 14:53:15
Sub 正規表現()
Dim hoge, strpat As String, hogeMatch
Set hoge = CreateObject("VBScript.RegExp")
strpat = ".*?(\n|$)"
With hoge
.Pattern = strpat
.IgnoreCase = True
.Global = True
End With
Set hogeMatch = hoge.Execute(Cells(1, 1))
If hogeMatch.Count > 0 Then
Debug.Print (hogeMatch(0))
Debug.Print (hogeMatch(1))
Debug.Print (hogeMatch(2))
End If
End Sub

こんな感じで取得は出来たよ。
submatchはあまり詳しく無いんで分かりません。
取り出した文字列には、改行文字も含まれてるので、
取り出した後に replace で vblf を "" に置き換えて除去すると良いかもね。

537 :デフォルトの名無しさん:2008/07/21(月) 14:54:51
あ、取り出される要素数がその都度違うようだったら、
hogeMatch.countの回数だけ繰り返してね。

538 :デフォルトの名無しさん:2008/07/21(月) 14:57:35
ああ・・・ vblf で split するのが一番良かったかもしれませんね・・・。
スレ汚しすいませんでした。

Sub piyo()
Dim hoge
hoge = Split(Cells(1, 1), vbLf)
Debug.Print (hoge(0))
End Sub

ごめんなさい。

539 :デフォルトの名無しさん:2008/07/21(月) 16:00:42
>>536
改行コードがLF固定だったら、
MultiLine = True, Global = Trueにした上で
"^.*"でやれば無駄な改行コードも取れずにそのまんますんなり行ける。

540 :デフォルトの名無しさん:2008/07/21(月) 17:04:38
ああ、multilineでセル内改行取れましたね・・・。勉強になります。

541 :デフォルトの名無しさん:2008/07/21(月) 18:46:02
行分割するだけなのに、何故に外部コンポ引っ張り出して正規表現使う必要が・・・・・

542 :デフォルトの名無しさん:2008/07/21(月) 19:52:55
そう言う年頃なんだろよ。

543 :デフォルトの名無しさん:2008/07/21(月) 23:33:06
頭でっかち

544 :y:2008/07/22(火) 00:41:47
>>519
ありがとうございます。
うちはExcel2003ですが、次のような結果でした。

@test(i) →4227
Atest(i as Integer) →5216
Btest(i, j) →3453

@とBは全く同じ結果ですね。
となるとスタック領域は、メモリ環境依存ではなく
やはり仕様で決まっているのでしょうか。
@よりAの方が多いのは何となく理解できます。
少なくとも単純に深さでないことは分かりました。
また暇を見つけて探ってみます。

>>540
私も、VBAを使うまでもないことにVBAを使って、
「それピボットテーブルでできるよ」
「それオートフィルタの条件指定で(ry
「ソルバー(ry
みたいな指摘を受けてしばしば鬱になります。


545 :デフォルトの名無しさん:2008/07/22(火) 00:57:40
Application.MemoryTotal / MemoryUsed / MemoryFree 等で
Excelのメモリ容量を取得できるから
スタック領域もExcelの使用可能メモリ量に依存するんじゃないの?


546 :y:2008/07/22(火) 01:33:32
>>545
そのプロパティ、初めて知りました。さっそく実験。
>>519の試験コードにおいて、プロパティの値を出力してみます。

Function test(i)
Debug.Print Application.MemoryUsed
Debug.Print Application.MemoryFree
test (i + 1)
End Function

予想では、再帰呼び出しがされればされるほど
使用メモリは増え、使用可能メモリは減ると思いましたが、
実際には出力される数値はまったく変化しませんでした。

スタック領域は、これらのプロパティで出力されるメモリ数とは別なのか、
それともこのプロパティは動的な意味でのメモリ容量ではないのか。



547 :デフォルトの名無しさん:2008/07/22(火) 01:37:49
メモリは確保済みなんじゃないの?いや、知らないけど

548 :デフォルトの名無しさん:2008/07/22(火) 02:08:06
これに書いてる
ttp://k-flow.blog.so-net.ne.jp/2008-03-24
>ちなみに、Application.MemoryFreeプロパティで得られるフリーメモリー容量は、どのような条件下においても、常に1MB程度です。
>また、Application.MemoryTotalプロパティで得られるトータルメモリ容量は、常に上記の2つのメモリ容量の合計となります。

これなら、スタックで使えるメモリ量も常に1MB程度って事じゃないかな?

549 :デフォルトの名無しさん:2008/07/22(火) 02:41:04
まあ再帰の数で困ったら
まず末尾再帰の形に書き直して(ステートを持ちまわるようにする)、
それからループに書き直すといいね。

550 :デフォルトの名無しさん:2008/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:2008/07/22(火) 22:40:40
>>550
あ、すみません。Aをその通りやり直したら6453でした。
>>519と比べて1だけ違いますが、これでほぼ同じ結果になりましたね。

>>549
末尾再帰と呼ばれるスキームも、初めて聴きました。Wikipedia「末尾再帰」のコード例は、全然知らない言語なので
私には理解不能です。でも、スタックオーバーフローを「回避できる」と確かに書いてあるので、できたら知っておきたいです。

色々検索したら、べき乗を求める再帰関数を末尾再帰の形に書き換えたというC言語のコード例を見つけたので
真似をしてVBAに書き直してみたのですが...
ttp://itpro.nikkeibp.co.jp/article/COLUMN/20060912/247768/
(このページの一番最後に紹介されています)

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 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/07/22(火) 23:32:13
ごめん。最後の関数のresult&はいらん。

554 :デフォルトの名無しさん:2008/07/22(火) 23:42:09
選択範囲をset して
For Eachでまわそうとすると
余分にまわりませんか?
Selection.Countでみるとときどきなんか多い…わらし?

555 :デフォルトの名無しさん:2008/07/22(火) 23:43:36
コード晒せよ

556 :デフォルトの名無しさん:2008/07/23(水) 04:35:09
>>552
君、うざいよ。

557 :y:2008/07/23(水) 17:10:26
>>552
なるほど、納得です。>>549の説明も意味が分かりました。
・再帰のコードは、普通のループ構造で表現できる。
・再帰のコードをいったん末尾再帰の形に直しておけば、ループ構造に直すのが容易。
・末尾再帰のコードは、『残りの操作』(戻り値を使った演算)が必要ないため、理屈としては呼出元の変数の状態を保存しておく必要がない。
・言語によっては(あるいは賢いコンパイラは)この性質を利用して、末尾再帰のコードを、同一関数のくり返しの形(ループ構造)に最適化してくれる。
 だから呼び出しのたびにスタックリソースの消費が増加することがない。
・でもVBAではそういう最適化はしてくれないから、最初から自分でループ構造に直して書く。

ありがとうございました。

>>554 >>555

558 :デフォルトの名無しさん:2008/07/23(水) 17:15:16
VBAで、GUID(グローバル一意識別子)を取得したいのですが、
なにか関数などはありますか?
GetGUID的な、都度ユニークなIDを返してくれるような。
C++の方法はわかるのですが、VBAでやる方法がわかりません。
よろしくお願いいたします。

559 :y:2008/07/23(水) 17:39:34
>>558
手元にあるリファレンスブックをざっと見ましたが、
そういう関数は私には見つけられませんでした。

その識別子を何に使いたいのか教えてくれたら、
他の方もアドバイスしやすいと思います。

560 :デフォルトの名無しさん:2008/07/23(水) 20:16:36
>>557
だいたいその認識でOK。
誤解の無い様に言っておくが、(勘違いしていたらすまんこ)
全ての再帰がループに直せるわけじゃなくて、末尾再帰だけね。

561 :デフォルトの名無しさん:2008/07/23(水) 20:34:49
>>558
VB GUID 生成

562 :デフォルトの名無しさん:2008/07/25(金) 11:11:35
>>559 >>561

ありがとうございます。
できました。
http://support.microsoft.com/kb/176790/ja

563 :デフォルトの名無しさん:2008/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:2008/07/26(土) 04:44:26
>>563の追記です。
1つのセル内には複数の文字列群があるため(A12とA123が同一セルにある)
xlWhole をつけてもだめでした。

565 :デフォルトの名無しさん:2008/07/26(土) 06:20:22
A123を先にB123に変換
A12を変換
B123をA123に変換
では多分駄目なんだろなぁ


566 :デフォルトの名無しさん:2008/07/26(土) 06:54:00
>>563
あくまでおいらのやり方ね。状況に応じて何種類か使い分けてるね。

>>565さんのやり方。
str1の検索ワードにlenでの長さを出して、降順にソート。長い物から置換して行く。

・オートフィルタで完全一致させる物を抽出。んでマッチにしたセルを置換。

・上二つや、組み合わせで対応出来ない時はregexpのreplaceを使う。(regexpの話出ると荒れるんだよね・・・)

たぶん、検索文字列と置換文字列がデータテーブルに存在するならば、
オートフィルタか、長い順に置換で出来るような気がするよ。

567 :デフォルトの名無しさん:2008/07/26(土) 06:57:31
>>564
>1つのセル内には複数の文字列群があるため(A12とA123が同一セルにある)

かぁ・・・・。
データテーブルを文字列の長い順にソートしてから、
オートフィルタの部分一致で抽出、見えてるセルにreplaceでどうかな。


568 :563:2008/07/26(土) 07:57:01
>>565 >>566 >>567さん
朝早くからご回答ありがとうございます!
今日夜にでも長い順にソートで試してみたいと思います。

569 :563:2008/07/26(土) 08:07:43
置換の>>563です、
あぁ・・・。
以下のような場合がマズイかもしれません。
もう少し調べたり考えたりしてみますね。

例)置換リスト A123→B123

対象データセルの文字列
A12 A123 A1234

※A1234までB1234になってしまう。

570 :デフォルトの名無しさん:2008/07/26(土) 08:56:38
一旦配列に取り込んでVBAでReplaceした方がいいんじゃないのかな

571 :デフォルトの名無しさん:2008/07/26(土) 09:00:50
あ、Replace関数使うんならLen関数も一緒に使うとかしないとダメだな

572 :デフォルトの名無しさん:2008/07/26(土) 09:02:27
置換条件が結構厳しそうだね。
replaceだと一致は理論上の部分一致だし、
1セルに複数の文字列が入ってるとなると、オートフィルタも限界あるなぁ。

regexpのreplaceメソッドが良いような気がするけど、詳しい人の意見も聞きたいな。
セルの中で、どんな風に文字が配置されてるかが分からないけど・・・まぁ行けるかと。

A12A123A1234 のうちA123だけを置換したいなら、 "A123^A"で引っ掛けられるかな。

573 :デフォルトの名無しさん:2008/07/26(土) 09:07:43
VBAのreplace使えるのって、A123もA1234も置換する場合に限られるような気がする。
もし、A123は置換するけど、A1234はそのまま、って場合にはちとまずい。


574 :デフォルトの名無しさん:2008/07/26(土) 09:54:55
だから配列に取り込むんだよ

575 :y:2008/07/26(土) 14:27:52
>>569
まず、>>563

>文字列A12をB12に置換したいが、
>文字列A123は置換せずそのままにしたい

と書いていますが、2つの要求同士が矛盾しているので、
そのような動作はありえません。

解決の可能性としては、>>572の「セルの中でどんな風に文字が配置されているか」がポイントです。
つまり、文字の配置に規則性があるかどうか、ということです。
たとえば>>569で、対象データセルの文字列として「A12 A123 A1234」という例が示されていますが、
これを見る限り「文字列に含まれる各単語は、スペースで区切られている」という規則性が感じられます。
もし、すべての対象データセルの文字列がこの規則に従っているなら、望みの操作は可能です。

まずはすべての文字列に共通する規則性があるかどうかを確認し、
もし上記のような規則が存在するなら、>>570>>574が薦めている
「配列にとりこむ」方法を検討してみてください。
この場合、Split関数が使えます。



576 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/07/26(土) 21:04:21
何でもかんでもVBAの機能だけでやろうとすんなって。
使える物は何でも使おうぜ。
VBSだろうがAPIだろうがWHSだろうが、VBAから使える以上、VBAで良いと思うぞ。

578 :デフォルトの名無しさん:2008/07/26(土) 21:27:32
Microsoft VBScript Regular Expressions
参照して、正規表現で置換かけるのはダメなん?

579 :デフォルトの名無しさん:2008/07/26(土) 22:58:50
完全一致を望むならば、やはり正規表現だと思う。


580 :y:2008/07/26(土) 23:48:07
>>576のレスを見て、全角と半角の混在に気づきました。
これではJoinは使えませんね...

私は正規表現は苦手で、普段はあまり使っていないのですが、
たしかにこの状況では正規表現が良さそうな気がしてきました。
半角・全角スペースどちらにもマッチしてくれる\bがかなり便利。
"\b(A12)\b" を探して "B12" にReplaceするだけで済みますね。


581 :デフォルトの名無しさん:2008/07/27(日) 02:43:35
>>577
具体的にどうやるのか示せよ

582 :デフォルトの名無しさん:2008/07/27(日) 08:18:41
どんな物を置換したいのか、どんな並びになってるのかが分かればマッチパターンを考える事は出来まっせ。

もし、住所録の置換なんかで、
○○県アルプス市〜〜 → ●●県foo市〜〜
××県南アルプス市〜〜 → △△県bar市〜〜
みたいなのだと、正規表現じゃないと無理ですな。

何にせよ、規則性を見つけ出してパターンを組む事から始めよう。


583 :デフォルトの名無しさん:2008/07/27(日) 11:20:14
XP Excel2003で質問なのですが

480×640の画像のRGBの値を画素ごとに
R(480,640),G(480,640),B(480,640)
という配列に読み込みたいのですが可能でしょうか?


584 :デフォルトの名無しさん:2008/07/27(日) 11:50:28
スレ違い

585 :デフォルトの名無しさん:2008/07/27(日) 12:37:40
画素ごとに・・・ってあんた。

586 :デフォルトの名無しさん:2008/07/27(日) 14:47:34
1000万画素の写真として、3000万個の配列ですか・・・。
考えただけで鬱・・・。

587 :640*480がどうやったら1000万になるんだw:2008/07/27(日) 14:57:49
>>586
もし暗算が苦手でしたら、WindowsにしろLinux(Gnome)にしろ電卓アプリが付属していますので是非お使いください。

588 :デフォルトの名無しさん:2008/07/27(日) 15:28:04
え・・・普通480×640って言ったら画像サイズの事じゃないの?
画素数は密度によって違うと思うんだけど。

589 :デフォルトの名無しさん:2008/07/27(日) 15:46:09
>>588
画像サイズが pixel 単位表記ではない可能性の話?

仮に mm 表記で 100dpi とすると
640mm/25.4*100≒2520pixel
480mm/25.4*100≒1890pixel
2520x1890=470万画素

590 :y:2008/07/27(日) 15:56:24
>>583

可能です。中級ぐらいのVBA解説書で時々見かける課題です。
まずは対象の画像ファイルをBinaryモードでOpenし、
配列変数にバイト単位で格納します。数行で済みます。
ttp://www.cocoaliz.com/excelVBA/index/47/

次に、その画像のファイル形式の仕様に沿って、画素データを抽出する
だけですが、画素ごとの色データを取得するのが目的であれば、
24bitモードのBMP形式の画像ファイルがもっとも簡単です。
他の形式の画像ファイルでも、いったん24bitのBMP形式に保存しなおして
から処理するといいでしょう。

BMP形式の仕様はこうなっています。
ttp://www.kk.iij4u.or.jp/~kondo/bmp/

データ部には、1画素につきRGBの順で各1バイト(計3バイト)の
色データが並んでいます。(注意が必要なのは、並びが最下行から最上行の
方向になっている点です)
上記2サイトを参考にチャレンジしてみてください。

591 :デフォルトの名無しさん:2008/07/27(日) 15:58:56
エクセルっていろんな事出来るんだね・・・ほんとすごいです。

592 :y:2008/07/27(日) 16:24:18
すみません。>>590は「VBA解説書」→「VB解説書」の間違いです。
さすがにExcelVBAの解説書で、画像ファイル処理の例は見たことはありません。
ある意味>>584ですが、ついつい答えてしまいました。

593 :583:2008/07/27(日) 16:57:26
画像サイズと画素数を混用してしまったせいで変な誤解をさせてしまったみたいです
すみませんでした。

>>590
非常にわかりやく解説していただいてありがとうございます!
ずばりこれを知りたかったんです。
ありがとうございます。

594 :デフォルトの名無しさん:2008/07/27(日) 23:06:38
結局、置換の質問した人はうまく出来たのかな。

595 :デフォルトの名無しさん:2008/07/28(月) 01:39:56
今頃痴漢してつかまってるよ

596 :デフォルトの名無しさん:2008/07/28(月) 07:04:35
( ´_ゝ`)

597 :563:2008/07/28(月) 22:36:20
ご報告が遅くなりましてすいません。置換の人です。

みなさんの知恵をお借りして、
私のつたないプログラム能力でなんとか作ってみました。

結局、セルを1つずつ読み込んで、
セル内の文字列に対してregexp正規表現 \b(str)\b で置換 
という形にしたところ、要求を満たすことができました。
みなさんありがとうございました!

598 :デフォルトの名無しさん:2008/07/28(月) 22:53:14
おめでとう

599 :デフォルトの名無しさん:2008/07/29(火) 11:57:03
入力された文字が漢字か平仮名かを判定することは可能でしょうか?

600 :デフォルトの名無しさん:2008/07/29(火) 12:05:21
はい。

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

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

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

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

こいつを具体的に。

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

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

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

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


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

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

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

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

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

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

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

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

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

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

Shell strComponentPath & "bld.bat"

に置き換える。

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

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

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

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

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

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

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

624 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/08/01(金) 15:10:23
cells(1,1).end(xldown)
で、可視セルを1段ずつ下げて行くとか?

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

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


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

628 :y:2008/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:2008/08/01(金) 22:41:09
>>626

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

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

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

630 :y:2008/08/01(金) 22:53:57
>>614

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

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

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


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

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

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


632 :デフォルトの名無しさん:2008/08/02(土) 00:05:45
>>631
ほとんどかわらないみたい
ttp://officetanaka.net/excel/vba/speed/s5.htm

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

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

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

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

637 :y:2008/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 :デフォルトの名無しさん:2008/08/02(土) 16:49:03
僕はいつもこうしてます。気分的なもので。
こっちのほうが早いような気がしてます。

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

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

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

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


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

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

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

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

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

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

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

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

646 :617:2008/08/02(土) 20:18:35
>>623

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

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

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

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

648 :y:2008/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 :デフォルトの名無しさん:2008/08/02(土) 21:28:15
機能不全になる前に気づけよw

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

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

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

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


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

654 :デフォルトの名無しさん:2008/08/02(土) 22:33:09
ちなみにユーザ定義のシート関数のパフォーマンスなら↓に載ってた。
まあ、正確だとはいえないが、VBAが決して遅くないことがわかる。
http://www.spreadsheethell.com/codematic/Excel-development/Excel-Visual-studio/excel-user-defined-functions.htm

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

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

657 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/08/03(日) 00:15:53
Range("C3") = Range("A3") でおっけ

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

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

cells(i,j).copy

とか?

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

662 :657:2008/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 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/08/03(日) 22:28:16
おっと

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


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

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

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

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

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

671 :y:2008/08/04(月) 14:08:37
>>667

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

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

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


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

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

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

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

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


すげーむかついた
vista視ね

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

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

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

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

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

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

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

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

という事であれば、

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

689 :デフォルトの名無しさん:2008/08/05(火) 21:30:04
難しい言い回しにしなくてもいいと思うよ
http://www005.upp.so-net.ne.jp/aoken/sas/sas_iom_xls.html

690 :y:2008/08/05(火) 21:38:27
>>685

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

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

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

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

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


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

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

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

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

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

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

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

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


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

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

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

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



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

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

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

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

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


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

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

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

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

699 :y:2008/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 :デフォルトの名無しさん:2008/08/05(火) 23:12:36
COM経由で呼べる組み込み言語ってないだろうか。
適当にJScriptインタプリタ起動できたりしないのだろうか。厳しいかな。

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

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

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

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

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

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

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

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

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

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


707 :y:2008/08/06(水) 18:02:38
>>706

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

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

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


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

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


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


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

713 :デフォルトの名無しさん:2008/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:2008/08/07(木) 17:31:25
>>713
やりたいことは、何となくわかりました。
・セルを上から一つ一つチェックして
・該当の行が見つかったら
・該当の行のデータを配列に書き込む
という流れですね。

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

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

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


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

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

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


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

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

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

721 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/08/08(金) 00:27:34
VBって、配列は弱いんでなかったっけ。
配列数指定しないといけないし。

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

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

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

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

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

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

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


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

730 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/08/08(金) 13:32:19
時間計るのに、ミリ秒まで計る方法ってある?

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

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

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

>>718-719
85 milliSec

>>730
20 milliSec

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

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

ちなみに、ミリ秒単位の時刻を得るために、
ttp://members3.jcom.home.ne.jp/daruma_kyo/info/getMilliSec.html
で公開されているモジュールを利用しています。

736 :デフォルトの名無しさん:2008/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 :デフォルトの名無しさん:2008/08/08(金) 21:18:52
ExcelVBAでやる時点で間違っている

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

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

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

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


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

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

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

>>739
ですよねー

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

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

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

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

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

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

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

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

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

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

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

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


749 :746:2008/08/09(土) 13:43:59
>>747

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


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

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

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

751 :デフォルトの名無しさん:2008/08/09(土) 22:49:35
エスセルVBAがすきだたですが

752 :746:2008/08/10(日) 03:48:25
>>750
ユーザーフォームでやってみました。 うまく出来ました。

もうひとつお聞きしたいことが、
ボタンを押すとユーザーフォームが出るようにしたのですが、いくつものユーザーフォームを作り、ボタンを押したら、
ランダムでユーザーフォームを表示することは出来ますか?


753 :デフォルトの名無しさん:2008/08/10(日) 07:10:45
>>626 等でグラフ補完を質問したものです。
そのときの回答>>629をヒントに
いらない部分の線を消すことで解決しました。
しかしExcel2003で開発していたのですが、
Excel2003では異なった場所の線が消えていました。

他のバージョンでも同様の結果を出すためにはどうすればよいでしょうか?

754 :デフォルトの名無しさん:2008/08/10(日) 08:26:21
シートに写真を複数枚挿入し、そのサイズ変更を一括で行うにはどうすればいいですか?
シートには写真以外の図形オブジェクトもあり、それらは選択も変更もしません。

jpgだけを複数選択やワイルドカードなど使えるのでしょうか?
  1枚だけマクロ記録するとこうなります。
ActiveSheet.Shapes("Picture 1").Select
Selection.ShapeRange.LockAspectRatio = msoTrue
Selection.ShapeRange.Height = 150.75
Selection.ShapeRange.Width = 201#

755 :デフォルトの名無しさん:2008/08/10(日) 09:23:27
>>754
for each

756 :y:2008/08/10(日) 12:04:40
>>753
線分を消す部分のコードだけで構わないので、あなたが書いたものを貼ってください。
それに加えて、何番目の点と何番目の点の間の線分を消すつもりだったのかと、
その意に反して、どの線分が消えてしまったのかも書いてください。


757 :デフォルトの名無しさん:2008/08/10(日) 13:00:09
ぬるぽですか

758 :デフォルトの名無しさん:2008/08/10(日) 13:07:35
y消えろ

759 :デフォルトの名無しさん:2008/08/10(日) 13:39:51
>>753
訂正します。
>しかしExcel2003で開発していたのですが、
>Excel2003では異なった場所の線が消えていました。
Excel2003で開発してExcel2002では異なる結果でした。

Excel2003でコード実行し計算した結果グラフをファイルに保存し、
それをExcel2002で見るだけで異なる線が消えている。。。
またExcel2002で見た(異なる線が消えている)グラフを、再度Excel2003で見ると正常になる。

どうもグラフの順番のつけ方?の定義のようなものが異なるのではという感じがします。
コードのせいではないと思います。

しかしコレでは駄目なので。。。うーん悩ましい。


760 :デフォルトの名無しさん:2008/08/10(日) 15:16:36
本人に悪気はないんだろうけど、コテハン使うなら、
他の人がせっかく答えてるのに、被せて回答するのはやめた方が良い。

他の答えてる人の面目丸潰れだよ。
んでみんな答える気が失せて行く。

761 :デフォルトの名無しさん:2008/08/10(日) 15:22:20
本人を特定できるコテつけて発言してるなら別だが
名無しで面目もないもんだ

762 :デフォルトの名無しさん:2008/08/10(日) 15:34:27
IDもでないしね

763 :デフォルトの名無しさん:2008/08/10(日) 17:29:45
>>760
こういう手法もある、とか提示してくれる分にはいいんでない?
セオリーや最短の方法イコール最善の方法、になるとは限らないし
傍目でROMってる人のレベルにうまくマッチする場合もあるしね

764 :デフォルトの名無しさん:2008/08/10(日) 19:16:42
勉強のために答えてるんだから大目に見てやれよ
それに他の人の面目が潰れるほどの良回答はまだまだ出来てないじゃん
彼に面目潰されるようじゃ、潰された方がレベル低すぎってものだ

765 :デフォルトの名無しさん:2008/08/10(日) 20:41:50
マターリやりましょ。
しかし最近は外部関数呼ぶ話が増えてきましたな。


766 :y:2008/08/10(日) 21:14:24
>>759
そうなんですか。失礼しました。
うちには2003しかないので、残念ながらその状況を再現できません。
2002のほうで、2003で実行したのと同じコードを実行するとどうなりますか?
やはり2003とは異なる線分が消えてしまいますか?

グラフの書式の仕様というと、Excel的にはとても大切なところなはずなので、
バージョン間でそう簡単に定義が変わるとは思えないのですが...

767 :デフォルトの名無しさん:2008/08/10(日) 21:23:48
>>759
一度2002でもマクロの記録でやってみれば
それでコードの問題かわかるだろ

768 :デフォルトの名無しさん:2008/08/11(月) 01:13:09
TMR!TMR!

769 :デフォルトの名無しさん:2008/08/11(月) 09:02:55
>>767
2002はもっていないんです。
使用者からのバグ報告なので。

770 :y:2008/08/11(月) 19:08:16
>>769
2002で試せないなら、残念ですが私はもうお手上げです...

771 :デフォルトの名無しさん:2008/08/11(月) 19:36:35
VBAと関係ない話なんでスルーしてもらって構わないんだけどさ。すごく気になったんで。

バージョンが多数存在するソフトの場合、金取って受注するならば、
可能な限り古いバージョンまで持っておかないとダメだよ。

金取って作業するならば、鉄則なんで。

772 :デフォルトの名無しさん:2008/08/11(月) 19:42:22
Windows95サポートですね、判ります。

773 :デフォルトの名無しさん:2008/08/11(月) 20:22:25
OSって意味じゃない。

774 :デフォルトの名無しさん:2008/08/11(月) 20:52:48
> バージョンが多数存在するソフトの場合、金取って受注するならば、
> 可能な限り古いバージョンまで持っておかないとダメだよ。
そんなことは無い
クライアントの発注要項に対応できるバージョンが揃ってれば問題ない
逆に考えれば、所有する環境で対応出来ない要項の発注は受けなければ良いだけ

プログラムに限った話じゃないが、自分(自社)に何が出来て何が出来ないのかを把握して
それに見合った受注をすれば良い、これこそが鉄則
設備、環境、能力以上の受注をしてしまうのは愚の骨頂だが、
何でもかんでも揃えようとするのもまた愚かしくある

もちろん、事業拡大、売上向上の為には良い設備環境を整えるというのは大事だが
「可能な限り古いバージョンまで持っておかない」と、金取っての受注が一切出来ないわけでもないし
「可能な限り古いバージョンまで持っておく」ことが、金取って受注する上での鉄則でもない

それと、VBAの場合はOSも関係有るよ
Office(Excel)自体もOSのコンポーネント使ってるし、VBAからはCOM、Win32API、OCXなど
様々なOSのコンポーネントを任意で呼び出せる
故に、当然ながらOffice(Excel)のバージョンが同じでも、OSが変われば結果も変わることがある
場合によってはOSのSPが変わっただけでも影響があるくらいだからな

775 :デフォルトの名無しさん:2008/08/11(月) 23:33:16
別bookの「ホゲ.xls」が開いてればそれをアクティブに、開いてなければ開くというコードを教えてください。

776 :デフォルトの名無しさん:2008/08/11(月) 23:45:03
>>775
Sub activate_forcefully_hoge()
On Error GoTo hoge_is_none
Dim hogePath$: hogePath = "C:\hoge.xls" ' ホゲ.xlsのパス
Dim hogeFileName$: hogeFileName = "hoge.xls" 'ホゲ.xlsのファイル名
Dim activated As Workbook
Set activated = Workbooks(hogeFileName)
GoTo activation
hoge_is_none:
Set activated = Workbooks.Open(hogePath)
activation:
activated.Activate
End Sub


777 :775:2008/08/12(火) 00:00:21
>>776
ありがたいけど・・・わかりやすくダイレクトに
if Workbookなんたらこうたら("ホゲ.xls")がない then Workbooks.Open Filename:= "ホゲ.xls"
という形で出来ませんでしょうか?
if のあとのいいメソッドかなんか無いですか?


778 :775:2008/08/12(火) 00:11:32
On Error GoTo hoge_is_none
Windows("ホゲ.xls").Activate
hoge_is_none:
Workbooks.Open Filename:= "ホゲ.xls"
Windows("ホゲ.xls").Activate
これでうまくいきました、ありがとう

779 :デフォルトの名無しさん:2008/08/12(火) 15:40:13
VBAに詳しい方お願いします。


 A列 B列 C列 D列 E列 F列 G列 H列 I列 J列…
1  1 010  a   AB
2  1 010  a      春  夏  秋  冬
3  1 010  a      上  下
4  2 020  b   BC
5  2 020  b      花
6  2 020  b      陸  空
6  2 020  b      水

:
:
↑を↓に変える記述教えてください。。

 A列 B列 C列 D列 E列 F列 G列 H列 I列 J列… 
1  1 010  a   AB
2  1 010  a      春 
3  1 010  a      夏
4  1 010  a      秋
5  1 010  a      冬
6  1 010  a      上
7  1 010  a      下
8  2 020  b   BC
9  2 020  b      花
10  2 020  b      陸  
11  2 020  b      空
6  2 020  b      水
:
:


780 :デフォルトの名無しさん:2008/08/12(火) 15:46:55
>>779
いいか。マクロの記録ってやつを使うんだ。
んで、並び替えしてみればほぼ再利用可能なコードが出来るはずだ。

781 :デフォルトの名無しさん:2008/08/12(火) 16:52:19
マクロの記録をしてからができないんです。。
ifとかDo Whileとか、、、

E1に値が入っていないのでカーソルを下に移動(E2へ移動)
 E2に値が入っているのでカーソルを右に移動(F2へ移動)
 F2に値が入っているので下(3行目)に新しい行を挿入し、(A2,B2,C2) を コピーして、(A3,B3,C3)に貼り付け、F2を切り取りE3に貼り付け る
 これをF2、G2、H2と繰り返してI2で空欄が出るまで続ける。
E8に値が入っていないのでカーソルを下に移動(E9へ移動)


  って感じにしたいんです(TT)

782 :デフォルトの名無しさん:2008/08/12(火) 18:01:50
最近勉強し始めたばかりなので
初歩的な質問かもしれませんが
ヒントください。

オートフィルタの抽出で
If A.Value = True Then
Sheets("○○○").Select
Range("A1").AutoFilter Field:=8, _
Criteria1:="*" & A.Value & "*"
End If
というコードを作ったのですが
フィルタがうまくかかりません。
(A.valueはユーザーフォームのテキストボックスです)
Aにいれるテキストが全角かな文字であるがために
プログラムが反映されてないのではと思うのですが
A.valueをA.Textにするとエラーがでます。
(A.text = true というのが無理っぽいです)
解決策があれば教えていただけないでしょうか。
よろしくお願いします。

783 :y:2008/08/12(火) 20:28:12
>>782
If の条件式についてですが、
「テキストボックスAに、何か文字が入っていれば抽出を行う」
という意図ですか。そういうことであれば、

If A.Value <> "" Then

にするといいでしょう。


784 :デフォルトの名無しさん:2008/08/12(火) 21:07:42
>>779
質問にやさしく親切に答えてくれるスレ 3
http://pc11.2ch.net/test/read.cgi/tech/1167125332/886
なんだ、マルチか。

785 :デフォルトの名無しさん:2008/08/12(火) 21:25:02
>>783 ありがとうございます!!!
うまくいきました!!
2〜3日ずっと悩んでいたので本当に感謝!!
ありがとうございましたm(_ _)m

786 :y:2008/08/12(火) 21:28:33
>>779

Dim r As Long, c As Integer, cc As Integer, dr As Long, dt As Variant, rNum As Long
rNum = WorksheetFunction.CountIf(Range("D:IV"), "<>")
ReDim dt(1 To rNum, 1 To 5)
r = 1: dr = 1
Do While Cells(r, 1) <> ""
 If Cells(r, 4) <> "" Then
  For c = 1 To 4
   dt(dr, c) = Cells(r, c)
  Next
  dr = dr + 1
 ElseIf Cells(r, 5) <> "" Then
  c = 5
  Do While Cells(r, c) <> ""
   For cc = 1 To 4
    dt(dr, cc) = Cells(r, cc)
   Next
   dt(dr, 5) = Cells(r, c)
   c = c + 1
   dr = dr + 1
  Loop
 End If
 r = r + 1
Loop
With ThisWorkbook.Sheets.Add
 .Range(.Cells(1, 1), .Cells(1, 1).Offset(rNum - 1, 4)) = dt
End With

もっと効率的な方法で書ける方もおられると思いますが...
それと、マルチ(複数のスレッドで同じ質問をすること)はしないようにしてくださいね。


787 :デフォルトの名無しさん:2008/08/12(火) 23:12:20
どなたかプログラマ向けの難しめのVBAの書籍(洋書でも可)を御存知ないでしょうか。
Excel Hacksとかではなく、VBAやらCOMとの絡みなど詳細な事項などが書いてあると嬉しいです。

いざ勉強しても何か心許ない感じになってくるので、
Oreilly的な本を一冊読んできちんと理解しだいです。
御存知でしたら、助言お願いします。

788 :デフォルトの名無しさん:2008/08/12(火) 23:46:38
y大人だなぁ

789 :デフォルトの名無しさん:2008/08/13(水) 00:11:46
COMってのは不特定多数が制作しているものだから
MSが作ったCOM以外を書籍で解説することはまず無いし
MSが作ったCOMに関してならMSDNにも情報がある

そしてExcel VBAに関しては、>>1★3にも有るとおり
Excelの操作をGUIではなく言語でやってるだけであり
突き詰めたところでそう難しいものでも無い
その先を行きたいならVBAではなくVBの範疇になるので
VBの書籍を買え

790 :デフォルトの名無しさん:2008/08/13(水) 02:00:39
>>789
すみませんが、VBでもいいので、
VB6互換の環境について、書籍を御存知ないですか?

791 :デフォルトの名無しさん:2008/08/13(水) 02:37:31
vb6ってたとえば関数のオーバーロードとかクラスのインヘリットとかがない等、
C++とかに比べて言語仕様自体に機能が多いわけじゃないから、アルゴリズムさえ
コードにできればリファレンス読むだけで十分な言語なんですよね?
高度な書籍っていっても結局vb6の機能をフルに活用して何が出来るかとかいう書籍がほしい
んだったら、結局vb6からAPIやCOM使ってなんかするサンプルコードなんかが沢山載ってる本
をほしいって事と同じようなものだと思うから、結局vbの枠で書籍を探すよりも、むしろ
COMの本買うとか、めんどくさいからvbやめて別の言語に手を出して、C++詳説の本買うとか
しないといけないんじゃないかなぁと思うんですが。どうなの?


792 :デフォルトの名無しさん:2008/08/13(水) 02:47:33
とりあえずここらへんにしておこうかな
http://www.amazon.com/Advanced-Visual-Basic-Techniques-DevelopMentor/dp/0201707128/
http://www.amazon.com/Programming-Microsoft-Visual-Basic-6-0/dp/0735605580

>>791
言語仕様自体はあまり明確じゃない言語だと思います。
クラスのインヘリタンスはあるにはありますね。ひ弱ですが。

古い言語のせいか、Webにある資料もいまいちどうもパッとしないのです。
C++はまあ別にどうでもよいので(知っているので)、
COMに?興味が出たらCOMの本買うと思います。若干時代に逆行していますが。

私としてはVB6/VBAのバイブルみたいなものを探していたところです。
一応、上記の本読んでみることにします。

793 :792:2008/08/13(水) 02:48:23
古い言語といっても、まあ、新しいわけだけれど、
陳腐化したといったほうがよかったかな。

>>791さん、お付き合いありがとうございました。

794 :デフォルトの名無しさん:2008/08/13(水) 06:49:43
VBA上級テクニック なんちゃらって本があったな。
API関数やVBSの呼び出し方が解説してあってよかったかも。
ただ、具体的なAPI関数についての説明なんかは当然なし。

当時、具体的な呼び出し方が説明してあるのは役に立った記憶があるよ。
あと、何で変数の型が必要か、とかrangeの概念なんかも詳しく説明してあった。
それまで全部variantで使ってた変数の型も、きっちり宣言出来るようになったし、
何となく使ってたfor eachも、何がどう動いてるのかが理解出来たよ。


795 :デフォルトの名無しさん:2008/08/13(水) 08:14:00
Range以外は全てVB6分野の話だな

796 :デフォルトの名無しさん:2008/08/13(水) 08:58:00
InputBoxを使った入力について教えてください。
セルのコメントをInputBox関数で入力させるマクロを組んでいます。
この入力値を、任意の箇所で改行したいのですが、できますか?
可能な場合、InputBox関数で呼び出される入力ダイアログボックス
にはどのように入力すれば良いのでしょうか?
ご教示お願いします。

797 :デフォルトの名無しさん:2008/08/13(水) 09:34:30
どうしてもInputBox使いたいなら、任意の文字列を改行として扱うしか無いかな

Dim strTemp As String
strTemp = InputBox("改行したい部分に\nを入れてください。", , "1行目\n2行目\n\n4行目")
strTemp = Replace(strTemp, "\n", vbCrLf)
MsgBox strTemp

改行扱い文字列は、別に\nじゃなくても本文中に出現しないものなら何でも良い


でも、ユーザーフォームで複数行入力できるダイアログを作るのが正攻法だろ

798 :デフォルトの名無しさん:2008/08/13(水) 10:07:04
できました。Replaceすればいいのですね。
ありがとうございました。

799 :デフォルトの名無しさん:2008/08/13(水) 10:30:48
Aというシートからユーザーフォームのテキストボックス(10個ぐらいある)
に入力された内容に従ってデータを抽出して
既存のBシートに貼り付けるような比較的長いコードを作りました。

最終的には、もしユーザーフォームの
「新規シートを作成して貼り付け」という
チェックボックスにチェックが入っていた場合は
Cシートを新たに作成し、そこにデータを貼り付け
さらにDシート・・Eシートとシートを増やせるようにしたいと
思っています。
その場合は
現在作ってある長いコードを使って
if checkbox1 = true then
 worksheets.add
「新しいシートに貼り付けてね」という長いコード
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
else 「シートBに貼り付けてね」という長いコード

end if
という風に、指定するシートを変えるだけで
ほとんど同じコードを2回記述するしか方法はないでしょうか??
もっと完結にできる方法があれば教えてください。
モジュールがやたら長くなって見にくくなってしまうのを回避したいです。





800 :デフォルトの名無しさん:2008/08/13(水) 11:30:00
>>799
共通する部分の処理でプロシージャを作り
Callで呼べばいい

801 :デフォルトの名無しさん:2008/08/13(水) 11:50:00
>>800 ありがとうございます!!
さっそく試してみます。

ステートメントを早くいろいろ覚えないと
後で「こんなステートメントあったんだ!じゃぁあの時
もっと簡単にプログラムできたじゃん!」って思うことが多いです(;;
もっとよく勉強します。
本当にありがとうございました。

802 :デフォルトの名無しさん:2008/08/13(水) 11:55:04
>>801
>後で「こんなステートメントあったんだ!じゃぁあの時
>もっと簡単にプログラムできたじゃん!」って思うことが多いです(;;

それが糧になるんだよ。決して無駄にはならないさ。
# 仕事なら話は別だが。

803 :デフォルトの名無しさん:2008/08/14(木) 10:48:11
アクティブシート上にあるすべてのボタンを消去するのって
ActiveSheet.Buttons.Delete
じゃ駄目なんですか?
いくら実行しても何も起こらないんですが。

804 :デフォルトの名無しさん:2008/08/14(木) 10:58:14
画面に向かって「消えろー」って10回叫べば消えるかも

805 :デフォルトの名無しさん:2008/08/14(木) 11:13:52
for each

806 :デフォルトの名無しさん:2008/08/14(木) 11:27:47
>>803
゙ボタン゙と言っているのはオートシェイプ?マクロ用のボタン(名前忘れた)?

807 :デフォルトの名無しさん:2008/08/14(木) 11:53:50
>>806
オートシェイプです。

すいません、今調べたら
ActiveSheet.DrawingObjects.Delete
という命令でシート上のボタンはすべて消せることがわかりました。

追加で質問なんですが、一行目に配置されたボタンだけを残し、二行目以降のボタンをすべて消去する方法ってありますか?


808 :デフォルトの名無しさん:2008/08/14(木) 12:07:36
>>807
プログラム化するならわからんが、オブジェクトの選択(矢印の付いたアイコン)
で範囲選択したら、その領域内に含まれる図形は全て選択できるからデリートで消す

809 :デフォルトの名無しさん:2008/08/14(木) 12:24:34
>>808
デリートでセルを消してもそのセル上のボタンは幅が0になるだけで線になって残りません?
完全に消去する方法が知りたいのですが。

810 :デフォルトの名無しさん:2008/08/14(木) 12:48:34
>>809
セルの行削除・列削除では消えませんよ。
図形描画のツールバーを出して、オブジェクト選択のボタンを使うべし。

811 :デフォルトの名無しさん:2008/08/14(木) 14:23:44
1行1件のデータシートがあります。
顧客 製品 台数
A あ 1
A あ 1
B あ 1
B あ 1
B い 1

これの顧客Bだけ範囲選択して
B あ 2
B い 1  という結果を別シートに出したいのです。
・選択1行目をコピー貼り付け
・2行目以降、前回顧客と製品名が一致したら台数インクリメント
・Activecell.Rows.Count数だけループ
という方法でなくもっといいのはありますか?


812 :デフォルトの名無しさん:2008/08/14(木) 17:16:40
CountIf

813 :デフォルトの名無しさん:2008/08/14(木) 17:52:52
>>811
ピボットテーブル知ってる?

814 :デフォルトの名無しさん:2008/08/14(木) 18:17:46
>>811
オートフィルタの抽出を別場所にする

815 :デフォルトの名無しさん:2008/08/14(木) 18:22:52
>>811
おいらならオートフィルタで指定の顧客名を抽出して、
if (cells(i,2).value = cells(i+1,2).value) daisu++}
ってインクリメントするかな。


816 :デフォルトの名無しさん:2008/08/14(木) 18:24:49
すいません。文法間違えました。
javascriptとしても間違えております・・・比較演算子違うし。

if cells(i,2).value = cells(i+1,2).value then
daisu = daisu + 1
end if

でした。本当に申し訳ない。

817 :811:2008/08/14(木) 18:32:04
目的は別シートに貼り付けるため、なのです。
全体を集計するのであればピボットで済みますが、そうではなく
必要な部分だけ抜き取って(項目も無し)それだけ集計して貼り付けたいのです。

手作業ではコピー、貼り付けしたあと、台数を修正して余計な行を削除
なんですがこれを自動化したいだけです。
標準の集計やピボットを利用するには、項目行もコピーしてシートも新しくせねばならず
また、完成した集計表では顧客名や製品名に勝手に空欄が出来てしまうので
使いたい形に修正するだけで作業が余計に感じます。

818 :デフォルトの名無しさん:2008/08/14(木) 18:35:25
これはマクロの記録で十分対応できるレベルだろ

819 :デフォルトの名無しさん:2008/08/14(木) 18:52:49
・選択部分を新しいシートにコピペ
・製品を軸に昇順に並べ替え
・製品名が変わるまでloop、んでカウント
・一番上の台数に代入
・代入した行にフラグ
・フラグ立てた行以外削除

こんな感じ?その情報でやるなら。
操作者が範囲を選択する時点で、選択ミスの可能性があるから、俺ならやらん。

きっと製品名は凄い沢山あるんだろうね。VBAスレで聞くって事は。

820 :y:2008/08/14(木) 21:33:06
>>817
うーん。ピボットテーブルはなるべく敬遠したいとのことですが、
必要な部分だけ抜き取ったり、ある項目だけの台数を合計したり、というのは
やはりピボットテーブルが本領を発揮する場面だと思うんですね。
「項目行もコピーしてシートも新しくせねばならず」とありますが、
ひとつピボットテーブルを作ってしまえば、あとはその設定を変えながら
運用すればいいわけです。
VBAでピボットテーブルも操作できることはご存知ですよね?
抜き出したい顧客に合わせてピボットテーブルの抽出アイテムを変えたり、
抽出結果を任意の別シートに貼り付けたりするような、手作業では
面倒な部分をVBAで自動化すればいいと思うんです。
全体をVBAで実現するやり方で考えていらっしゃる方もおられるので、
そちらも検討した上で、もう1つの考え方として受け取ってください。


821 :y:2008/08/14(木) 21:43:08
ピボットテーブルで処理する例です。

Sub ch_pivot()
Dim item As PivotItem, kName As String
kName = InputBox("顧客名を入力してください")
With Sheets("Sheet2")
With .PivotTables("ピボットテーブル1")
.PivotCache.Refresh
.PivotFields("顧客").PivotItems(kName).Visible = True
For Each item In .PivotFields("顧客").PivotItems
If item.Name <> kName Then item.Visible = False
Next
End With
Range(.Cells(5, 1), .Cells(.Rows.Count, 3).End(xlUp)).Copy _
Destination:=Application.InputBox("貼り付け先を指定してください", Type:=8)
End With
End Sub

822 :y:2008/08/14(木) 21:46:09
>>822のコードは、次のような前提で動作します。
(下のように設定されていないと動作しません)

○データシート
>>811のデータは"Sheet1"という名前のワークシートにおかれているとする。

○ユーザー定義の名前
・任意の名前(ここでは"pivotSource")を定義する。参照範囲は次のようにする。
 =OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),3)

○ピボットテーブル
・使用するデータの範囲を"pivotSource"とする
・レイアウトは行に"顧客"と"製品"。データに"台数"(集計方法は合計)。
・名前は"ピボットテーブル1"
・配置する場所は"Sheet2"という名前のワークシートの$A$3。
・顧客ごとの集計を非表示に
・列の総計を非表示に


823 :y:2008/08/14(木) 21:59:43
すみません。「>>822のコード」→「>>821のコード」の間違いです。
あとピボットテーブルはピボットテーブルウィザードなどを利用して
自分で設置してください。(セル範囲の名前の定義も自分で。)


824 :デフォルトの名無しさん:2008/08/14(木) 22:49:18
グラフを複数作成しようとしていますが、速度が10秒/1グラフと遅く
特に書式設定が速度的に遅いと感じます。

書式、データ数は同じで、データ内容だけ異なります。
グラフはチャート毎に1シートに描いているものです。
(埋め込みグラフじゃないほう?)

グラフの雛形的なものを使って複数グラフを作成し、
少しでも高速化したいと考えています。

実施したのですがデータの設定の順番が異なるのか、うまくいきません。
何かグラフコピーペーストのセオリーのようなものがあれば教えてください。


825 :デフォルトの名無しさん:2008/08/14(木) 23:26:51
>>824
screenupdate=Falseは既に実施しております。

826 :デフォルトの名無しさん:2008/08/15(金) 00:29:15
データの数とグラフの数が多いと遅くなると思いますよ。
オブジェクト数が多いとExcelの動作が劇的に重くなるのは仕様なのかな?
グラフ1つ作成するのに10秒かかるんだったらマクロの記録でグラフ作成するコード作って
比較してみればいいんじゃないですか?

827 :デフォルトの名無しさん:2008/08/15(金) 05:25:40
>>826
マクロの記録を参考に、いらない部分を削り、作成しました。
それで遅いので、複数グラフ作成で速くする方法はないかと考えました。


828 :デフォルトの名無しさん:2008/08/15(金) 05:45:16
質問があります。
正方行列(2×2)を一行(1×4)で表したとき、関数で配列(2×2)を作り、
さらにこの配列を関数で計算する方法が分かりません。例えば
1 2
3 4
の行列をエクセルシート上でA1:D1に1,2,3,4と入力したとき
=test(A1:D1)として配列(2×2)を作ります。

Function test(data As Range)
Dim A(1, 1) As Double
k = 1
For i = 1 To 2
For j = 1 To 2
k = k + 1
A(i - 1, j - 1) = data(k - 1)
Next
Next
test = A
End Function

このとき行列式(=1*4-2*3)を計算するため
=determ(test(A1:D1))とすると、#VALUE!となって困ってます。

Function determ(B As Double)
determ = B(0, 0) * B(1, 1) - B(0, 1) * B(1, 0)
End Function

いろいろ試してみたのですが、どうも配列の扱いがよく分からなくて。
XP Excel2003ですがよろしくお願いします。

829 :デフォルトの名無しさん:2008/08/15(金) 07:13:14
第一要因
 determ関数の引数が配列ではない
 配列を引数に取る場合は
 B() As Double
 のように、配列変数の後ろに () を付けなければならない

第二要因
 引数の型が合ってない
 配列を返す関数では、関数内で型を指定していても
 返される値はVariant型の配列となる

第三要因
 配列の要素数が合ってない
 シート上には0行目0列目が無いので、
 配列(1, 1) つまりは 配列(0 To 1, 0 To 1)
 を関数の結果として返すと、自動的に
 配列(1 To 2, 1 To 2)
 のように下限要素が0から1に変換される

以上を踏まえてdetermの方を
Function determ(B() As Variant)
  determ = B(1, 1) * B(2, 2) - B(1, 2) * B(2, 1)
End Function
とすれば動くと思う

ところで、>>828の例は質問用に簡素化しただけで、実際は配列要素数を決め打ちではなく精査してるよね?
あと、A(i - 1, j - 1) = data(k - 1) で、全部 -1 やってるのは何か意味有るの?

830 :828:2008/08/15(金) 07:54:20
>>829
早速ありがトン
急いで試してみたけど、なんかうまくいかない...

全部-1にしてるのは、配列は0から始まるって教わったので。
お察しの通り、本とは大きい行列なので、簡略化したんだけど。
=test(A1:D1)で配列をシートで見たけど合ってた。

ちょっとこれから会社なので、夜にまた試してみるよ。

831 :デフォルトの名無しさん:2008/08/15(金) 08:53:51
最低限、君が書いた例通り、A1:D1に1,2,3,4と入れて
=determ(test(A1:D1))
とする分には問題なく動く
上手く行かないとすれば、実際のコードに適応する上で君が何か間違ってるからだろう

あと、0から始まるのはそうなんだが、
For i = 1 To 2
For j = 1 To 2
k = k + 1
A(i - 1, j - 1) = data(k - 1)

For i = 0 To 1 '<- 1〜2ではなく0〜1
For j = 0 To 1
A(i, j) = data(k)
k = k + 1 '<- 変数kのインクリメントを後回しに
とすれば、3カ所の -1 は不要なんだが、何故わざわざi,j,kに1多い数を入れて -1 してるのかなぁと

832 :デフォルトの名無しさん:2008/08/15(金) 12:57:16
Excelでタブを作るのは無理ですか?

833 :デフォルトの名無しさん:2008/08/15(金) 14:24:13
へるぷみー。
テキストボックスに入力された名前を
新規のワークシートに付ける際に、例えば「あいうえお」という
名前のシートが既にあるにもかかわらず
テキストボックスに「あいうえお」と書かれた場合は
自動で「あいうえお1」次にまた「あいうえお」と入力されてしまった場合は
「あいうえお2」になるようにしたいと思い、
下記のようなコードを入力してみました。
(sheetnameがテキストボックスのオブジェクト名です)
Dim i As Integer, cnt As Integer, n As Integer
cnt = Worksheets.Count
n = 1
If CheckBox.Value = True Then
For i = 1 To cnt
Do Until sheetname.Value <> Worksheets(i).Name
sheetname.Value = sheetname.Value & n
n = n + 1
Loop
Next i
Worksheets.Add after:=Worksheets(cnt)
ActiveSheet.Name = sheetname.Value
End if

このコードだと
「あいうえお」→「あいうえお1」→「あいうえお11」
→「あいうえお111」
という風になってしまいました。
できるシリーズの本とかで調べたりWeb検索してみたりしたのですが
解決策が見つかりませんでした。
よろしくお願いします。

834 :デフォルトの名無しさん:2008/08/15(金) 15:52:13
>>833
どこがVBAの質問なんだか。単純な名前生成の問題じゃないか。
毎回シート名に"n"を継ぎ足すんじゃなくて、都度入力された名前に"n"を継ぎ足せばいいだろ。
オブジェクト変数を使いまわすんじゃなくて、一時変数で処理する癖をつけた方がいいな。

835 :デフォルトの名無しさん:2008/08/15(金) 17:07:40
>>832
何のタブかわからんが、ブックのタブならツールバーで作る手がある

836 :デフォルトの名無しさん:2008/08/15(金) 18:48:16
>>832
ユーザーフォームでタブを云々ならマルチページなりタブストリップなりをコントロールから追加

837 :デフォルトの名無しさん:2008/08/15(金) 19:03:27
ひとつのシートに複数のタブブラウザーみたいなのを作りたいと思っています。

838 :デフォルトの名無しさん:2008/08/15(金) 19:27:20
複数のシートにしちゃいけないの?

839 :デフォルトの名無しさん:2008/08/15(金) 20:10:50
ひとつのシートに複数のタブじゃないとダメなんです。できませんかねぇ。

840 :デフォルトの名無しさん:2008/08/15(金) 20:16:54
わざわざシートタブがあるのにそれを使わずに更にタブをつける理由も抜きに、「できませんかねぇ」じゃねぇよ。

841 :デフォルトの名無しさん:2008/08/15(金) 20:19:42
やろうとすれば出来るけど面倒

842 :828:2008/08/15(金) 20:21:18
>>831
たびたびありがとー

朝はバタバタしててできなかったけど解決しますた^^
ご指摘のとおりにFor文は0〜1にした方がすっきりしますね。

教科書とか読むとほとんど1〜だったのでなんか理由があるのかと
なんとなくこうしてました。

これで行列のいろんな演算ができそうです。
感謝、感謝

843 :デフォルトの名無しさん:2008/08/15(金) 20:38:15
ひとつのシートにタブを複数にする理由は本当はプログラムを組んでPOSシステムみたいなものを作りたいのですが知識がなく、それをExcelでと考えています。面倒でも構いませんから教えていただきたいです。

844 :デフォルトの名無しさん:2008/08/15(金) 20:43:01
>>843
道具には向き不向きというものがあるよ

845 :デフォルトの名無しさん:2008/08/15(金) 21:33:42
>>842
配列についてはExcel VBAのヘルプで Option BASE で検索してみて


846 :デフォルトの名無しさん:2008/08/15(金) 21:52:43
>>843
ボタンをタブに見立てて仮想的に実装すれば良い

これで解らないなら君には無理
諦めるか金払って作ってもらえ

847 :828:2008/08/15(金) 22:03:14
>>845
Option BASEで配列の最小値を0か1に選択できるのか
これは便利だわ
さんくす!

848 :デフォルトの名無しさん:2008/08/15(金) 22:26:03
Option BASEは基本使っちゃいけない機能の1つ

初心者がパッと見る限りは便利そうに見えるが
コードの明示性が著しく損なわれる

Option Private
Option Compare
も同じく、プロシージャや関数で逐一指定するのが正しい
逐一指定ではコードが長くなり冗長だと言う奴も居るが、冗長とは単に長いだけではなく無駄に長い意味もなく長いということで
これらの逐一指定は、それらの参照レベルや比較方式などを明示するという意味を持っているので冗長とはならない

グローバル変数の多用を害とするのも同じような理由から

849 :y:2008/08/15(金) 23:03:56
Option BASE 1 が期待通りに機能しない場合もあるので、それも頭に入れておいたほうがいいかも。
これを宣言していても、「Array 関数またはキーワード ParamArray を使って作成する配列の添字の最小値は 0 」
となってしまいます(ヘルプ参照)。Split関数が生成する配列も同様に Option BASE 1 の影響を受けません。


850 :デフォルトの名無しさん:2008/08/15(金) 23:17:43
>>834
ありがとうございます!
一時変数なるものについて勉強してから
それをヒントにもう一度よく考えてみます。

851 :デフォルトの名無しさん:2008/08/15(金) 23:19:17
それは「期待通りに機能しない」とは違う。
プログラムに置いて「期待通りに機能しない」というのは、
仕様書きに反する結果を返す場合などに使用する言葉。
「仕様通りに機能しない」とほぼ同義である。

Array、ParamArray、SplitなどがOption BASE 1の影響を受けないのは、
確立された仕様で常に同じ結果になるので、これが思惑通りじゃなかった場合は
「間違った期待をしていた」ということになる。
仕様を間違って覚えていたら、思惑通りに動かないのは当然のことだからね。

852 :y:2008/08/15(金) 23:33:36
あ、なるほど。その通りですね。


853 :デフォルトの名無しさん:2008/08/15(金) 23:43:46
別にそこまで字面にこだわるようなものじゃないと思うが。
期待通りに機能しない、というのは単純に使用者が想定しがちな
一貫性を提供しない、ということだろう。

854 :z:2008/08/16(土) 00:21:47
Application.Application.Application

855 :デフォルトの名無しさん:2008/08/16(土) 06:50:42
OPTION BASEってプロシージャで1回しか宣言出来ないのがなぁ。
ま、OPTIONだから当然なんだけどね。

他の言語はあまり数知らないけど、配列で0からスタートしない言語ってあるのかな。
2系列しか言語知らないけど、配列は0から始まる。って覚えてるから違和感はないな。


856 :デフォルトの名無しさん:2008/08/16(土) 06:57:54
>配列で0からスタートしない言語ってあるのかな

最近のCOBOLは違うかどうかまでは知らんけど、少なくともCOBOL85は1からスタート

857 :828:2008/08/16(土) 07:38:49
>>848
ご忠告ありがとー
Opttion BASE 1だと配列に格納する場合の添字と
配列から取り出すときの添字の値が同じだし、

行列の添字が一致するので便利と思ったけど、
使うときは注意したいと思います。

最終的には数千の行列を計算したいので逐一指定だけでは大変かと
思っていたけど、初心者の私にはまずこれでやってみます。

>>849
yさんありトンです
過去レスで配列のこともいろいろ書かれてますが
読み返すと少しずつ分かってきました。

Array関数などはまだ使ったことがないけど、
使うときにはOption Baseに添字が影響されないことを思い出します。

皆さん大変勉強になりました。初心者の質問に真摯に対応していただいて
なんかうれしいです。ありがとうございます。

858 :デフォルトの名無しさん:2008/08/16(土) 10:59:40
VBが嫌なのは普通に長さ0の配列を作れないこと

859 :デフォルトの名無しさん:2008/08/16(土) 11:00:38
ちょっと古い質問ですまんが、>>736
>> Const DATA_N As Integer = 50
>数値型、文字列型の定数で型指定するな
これってどういうこと?
Const DATA_N = 50
の方がいいってこと?

860 :y:2008/08/16(土) 11:58:13
>>858
長さ0の配列って、どんなことに便利なんですか?
アイテムを持っていないCollectionのようなイメージでしょうか。

861 :デフォルトの名無しさん:2008/08/16(土) 12:09:50
>>860
こういう一貫性のあるコードを書くことができる:
Dim anArray() As String
anArray = Split("") ' Variant()ならArray()でよし

For Each eachCell In [~~:~~]
ReDim Preserve anArray(UBound(anArray) + 1)
If pred(eachCell) Then anArray(UBound(anArray)) = eachCell
Next eachCell
別に例としてはなんでもいいんだけれども、
とにかく『空』の表現がないといろいろと面倒。

862 :y:2008/08/16(土) 12:48:05
ありがとうございます。空の状態から1つずつ追加する、みたいなイメージのコーディングが可能に
なるわけですね。にしても、Split("")という表現でそれを実現できるとは...
ローカルウィンドウで確認すると、代入直後の変数anArrayの型がString(0 to -1)なんてなっているあたり、
Base0の理屈からすれば正しいのかもしれないですが、たしかに普通じゃないですね。


863 :デフォルトの名無しさん:2008/08/16(土) 13:14:19
VBAならEnptyでいいのでは?


864 :デフォルトの名無しさん:2008/08/16(土) 13:45:38
JAVAあたりだと、配列数をredimする必要もなく、どんどんputして行けるんだよね。
それが良いとは一概に言えないけど、VBだとそこらへんが不便。

865 :デフォルトの名無しさん:2008/08/16(土) 15:58:34
Enpty?

866 :デフォルトの名無しさん:2008/08/16(土) 17:16:54
>>864
たぶんjava.util.List<E>のことを言っているのだと思うが、Javaでも
配列じゃダメ(というわけでもないがReDim無いので相当に面倒)だがね。

VBは標準でDictionary揃えていないあたりコレクションの取り扱いが面倒。

867 :デフォルトの名無しさん:2008/08/16(土) 17:53:35
は?コレクションならあるだろ

868 :デフォルトの名無しさん:2008/08/16(土) 18:02:01
エンプティダンプティ

869 :デフォルトの名無しさん:2008/08/16(土) 18:10:33
>>867
コレクションっていうのはJavaでいうコレクションのことね。
SetやらMapやらQueueやら。

870 :デフォルトの名無しさん:2008/08/16(土) 21:07:46
アホが

871 :デフォルトの名無しさん:2008/08/16(土) 21:08:17
Jamaだよ

872 :デフォルトの名無しさん:2008/08/17(日) 00:35:10
設定としては再計算を自動にしているのですが、マクロでやると、
エクセルのコマンドバーに「再計算」が表示されます。そこを自動にするため、
SendKeys "{F9}", True
を書いてみたものの何の役にも立っていません。
どのようにしたら、いいでしょうか?
ご教示願います。



873 :デフォルトの名無しさん:2008/08/17(日) 00:49:14
年月日時間の計算なのですが、
VBAで hoge = cells(1,1).value - cells(1,2).value とすると型が一致しないと怒られますが、
ワークシート関数で、 =A1-B1 とやると、うまく計算してくれます。

ワークシート関数にはVBAには無い自動整形機能などが付いているのでしょうか。

874 :デフォルトの名無しさん:2008/08/17(日) 00:49:59
言い方がおかしかったです・・・・。
どんなVBAの機能で計算されているのでしょうか。

875 :デフォルトの名無しさん:2008/08/17(日) 01:52:48
>>872
Sheet.Calculate使えばいいでしょ

>>873-874
そもそもVBAとExcelの演算はぜんぜん別物。
Excelの計算はVBAの機能などではない。

876 :デフォルトの名無しさん:2008/08/17(日) 01:54:13
あー、わざわざSheet指定じゃなくて、Application.Calculateの方がよさそうだな。

877 :y:2008/08/17(日) 02:01:48
>>872
ttp://support.microsoft.com/kb/248179/ja
ただし、Excel2002や2003でも、再計算をしても「再計算」の文字が消えない、
という状況はよくあるようですし、私も時々経験します。理由は分かりませんが、
シート上の数式の個数が多いと起こりやすい気がします。
しかし実際には、きちんと計算されているようです。

ちなみに、マクロで再計算を実行したい場合は、SendKeysよりもCaluculateメソッド
のほうが妥当です。

878 :y:2008/08/17(日) 02:03:20
>>875 すみません。被りました。

879 :872:2008/08/17(日) 02:52:19
2003 XPです。
再計算はされていません。再計算に続けてワークシートイベントのcalculateが
動くようにしているつもりなのですが、再計算のために手動でのF9キーを
押すと、きちんと再計算後のイベントが働き、目的が達成されます。
ただ、今日は、状況、目論見等の説明がうまく書けてないので、また、来ます。
夜遅くに、ありがとうございました。


880 :デフォルトの名無しさん:2008/08/18(月) 17:05:33
すみません。ご指導お願いします。。
100万行以上あるテキストファイルを、1万行づつ分割して
元のデータの形式、区切り文字、列のデータ形式
を指定し、エクセルシートに取り込んむVBAは可能でしょうか?
可能であるならどのようにしたらいいのでしょうか?(Accessは使わず)
  宜しくお願いします。


881 :デフォルトの名無しさん:2008/08/18(月) 18:19:56
>>880
で、幾ら払うの?

882 :y:2008/08/18(月) 18:54:52
>>880
偶然ですが、ちょうど私も500万件の氏名+ふりがなデータを使って
似たようなテストをやっている最中です(遊びで)。うちの場合は
1シートあたり5万行ずつで100シート分です。理屈としてはできるはずですが、
途中何が起こるかわからないので「可能です」とは言えません。

テキストファイルの取り込み方は、まず「テキストファイル VBA」とかで検索してみてください。
たくさん出てきますよ。


883 :デフォルトの名無しさん:2008/08/18(月) 19:40:16
>>880
Excelのバージョンによらない解決法は、
1. テキストファイルを順次読み込み、1万行分のファイルを作る
2. Excelの機能でテキストファイルを読み込む
3. 読み込んだシートをBookのシートにコピー
4. 1にもどる

884 :デフォルトの名無しさん:2008/08/18(月) 19:41:52
>>882
どう考えても「可能」だろ。
適当なこと言うなよ。

885 :デフォルトの名無しさん:2008/08/18(月) 19:50:10
名前とふりがなで1件50バイトとして5万行で2.5MB
100シートだから250MB
おれはexcelで30MB以上のファイル開いたことないなー

886 :デフォルトの名無しさん:2008/08/18(月) 20:05:49
Excelにデータを読み込むのが目的じゃなくて、読み込んだデータを何かに使うのが目的じゃないのか?
だとしたら、SQLiteとかの方がいいかもしれんぞ。

887 :デフォルトの名無しさん:2008/08/18(月) 20:09:55
いや、だったらmdbでいいだろ

888 :y:2008/08/18(月) 20:35:22
>>884
あ、可能なんですね。失礼しました。
こんなに件数が膨大だと、メモリの関係で途中で止まってしまうとか、その他不測の事態が
起こったりしないとは言い切れず、従って「可能」とも言い切れず...みたいな心境でした。

氏名生成を16:00頃に開始して、今でようやく400万件です。
テキストファイルで120Mbになっています。どうなることやら...


889 :デフォルトの名無しさん:2008/08/18(月) 20:43:24
というか、excelに向いてる事、向いてない事を考えろよ。

出来る。と向いているは全く違うぞ?
yみたいに遊びで試すなら何やっても良いけど、
仕事で使うなら、excelで大量のデータ処理をするなんて考えは捨てるべき。

と思ったけど、yは500万件の氏名データ持ってる時点で遊びじゃない。
もっと色々と自覚したほうが良い。

890 :デフォルトの名無しさん:2008/08/18(月) 20:52:46
>>880
速度気にせずその条件を実現するなら単にループを二重に回せば良いだけだろ。

外側はDo...Loopで、テキストファイルのデータが終わったら終了。
内側はFor...Nextで、1 To 10000のカウンタループ。

外側のループで新規シート作ったら、内側のループで1行分のデータを読み込み、
シートに入力していけば良い。データが無くなったらExit Doで一気に外側のループも抜ける。
内側のループ内でやることは、データが3行でも100行でも1000000行でも変わらない
まあ、データ量が多い場合は1行ずつ読み込まないで、全体を変数に取って処理したり
逐一セルに代入するより配列介した方が早いとかはあるけどな

内側のループ内でやること、つまり1行分を読み込んでExcelに適用することすら解らないと言うなら、
>>1★5読んで出直すか、>>881も言うように金払って作ってもらえ。

因みに、作成できるシートの数はシートの内容や環境依存で、
内容では使用行列数もそうだが修飾が大きく影響し、環境では主に物理メモリのサイズが影響する。

>>889
> と思ったけど、yは500万件の氏名データ持ってる時点で遊びじゃない。
持ってるんじゃなくて、プログラムのテストや勉強用で作る場合もあるだろ。
俺もVBAじゃなういが、自作プログラムのテスト用に住所氏名などの仮想データを数十万件と用意したこともある。
実用ではなくテストや勉強や遊び用なら、データは同じ氏名の繰り返しでも何ら問題ないからな。
俺の場合は10件くらいの適当な住所氏名の繰り返しにしたが。

891 :y:2008/08/18(月) 21:03:44
>>889
誤解ですよ〜(泣)。500万件の個人情報を握っているわけではなく、
このソフトで氏名を生成しているだけです。
ttp://www.vector.co.jp/soft/win95/amuse/se318543.html
>>890が察してくださった通り、大量の仮想データを使ったテストをしようとしています。


892 :デフォルトの名無しさん:2008/08/18(月) 21:36:25
Excelの仕様くらい調べてくれよ・・・

893 :デフォルトの名無しさん:2008/08/18(月) 21:47:54
何勘違いしてるの?

894 :デフォルトの名無しさん:2008/08/18(月) 21:52:50
どうしてもExcel VBAじゃないとだめなん?
今時珍しいぞあんな低速言語

895 :デフォルトの名無しさん:2008/08/18(月) 21:54:06
yが来るようになってから、このスレが変になった

896 :デフォルトの名無しさん:2008/08/18(月) 22:02:30
依存するのは物理メモリか?

897 :デフォルトの名無しさん:2008/08/18(月) 22:04:15
>>895
いいじゃん。活気があって。

898 :デフォルトの名無しさん:2008/08/19(火) 00:04:23
>>880は特に「単一のブックで」といった事は書いていないようだが
その辺は暗黙の了解なのだろうか

899 :デフォルトの名無しさん:2008/08/19(火) 11:22:06
みなさんありがとうございます。。
補足させてください。
フォルダの中に複数のテキストファイルがあります。
それをVBAで1シートに1テキストファイルづつで取り込んで
(区切り文字(#)、列のデータ形式(文字列)を指定して)
作成済みのマクロを実行し、出力させたいのですが。。
データが大きいので5シートで1つのファイルにしたいです。
フォルダの中にはテキストファイルが100ほどあるので、結果、エクセルファイルが
20できればいいのですが。。
できればデスクトップに新しいフォルダが作成されて
その中に出力されていくようにしたいです。
お力を貸してください。よろしくお願いします。

900 :デフォルトの名無しさん:2008/08/19(火) 11:28:39
現在、ユーザーフォーム上でワークシートを表示させるべく
スプレッドシートを設置することはできましたが、
このスプレッドシート上にチェックボックスを表示させる方法が分かりません。
何か良い方法があれば教えてください。お願い致します。

901 :デフォルトの名無しさん:2008/08/19(火) 21:35:33
>>899
質問というより丸投げの典型例

902 :デフォルトの名無しさん:2008/08/19(火) 21:37:14
>>899
ファイル名は連番のノンブルとか付いてるのかい?

フォルダに入ってるバラバラのファイル名のファイルを全部読み込む。
って言うならばVBAの範疇超えてるからスレ違い。

903 :y:2008/08/19(火) 22:38:26
>>900
SpreadsheetコンポーネントのSheetオブジェクトは、Excelシートと比べてとてもシンプルな機能しかなく、
OLEObjectsプロパティも持っていないため、CheckBoxなどのコントロールを追加する領域自体が見当たりません。
コンポーネントのヘルプにもとくに触れられていないようです。
普通にユーザーフォーム上にCheckboxを配置するだけでは足りないのですか?


904 :デフォルトの名無しさん:2008/08/20(水) 14:35:52
よろしくお願い致します。
OS:XP エクセル2003 VBAのことは、まったくの初心者です。
質問なのですが、下記のようなチェックボックス7にチェックが入れば、
チェックボックス8〜11に自由にチェックが入れれるようになり、
逆にチャックボックス7にチェックが入ってない場合は、
チェックボックス8〜11のチェックはクリアされ、
チェックできないものを作りました。

ここから、チェックボックス7にチェック入れたあとは、
必ずチェックボックス9〜11のどれかにチェックが入っている状態
(ラジオボタンのような)で、チェックボックス7にチェックが
入ってなかったら、8〜11のチェックがクリアで尚且つ、
チェックができなくなるようにするにはどうすればよいでしょうか? 
よろしくお願い致します。

Private Sub CheckBox7_Click()
If CheckBox7.Value = True Then
CheckBox8.Enabled = True
CheckBox9.Enabled = True
CheckBox10.Enabled = True
CheckBox11.Enabled = True
Else
CheckBox8.Value = False
CheckBox9.Value = False
CheckBox10.Value = False
CheckBox11.Value = False
CheckBox8.Enabled = False
CheckBox9.Enabled = False
CheckBox10.Enabled = False
CheckBox11.Enabled = False
End If
End Sub

905 :y:2008/08/20(水) 17:04:59
>>904
>ここから、チェックボックス7にチェック入れたあとは、
>必ずチェックボックス「9〜11」のどれかにチェックが入っている状態
とありますが、文脈からすると「8〜11」のつもりでしょうか?

8〜11にラジオボタン的な挙動をさせるには、
@CheckBox8〜11にそれぞれClickイベントプロシージャを作成
A各プロシージャには、自分以外のCheckBoxの値は全てFalse、自分の値だけをTrueにするコードを記述
すればよいかと思います。なお、「自分以外のCheckBoxの値は全てFalse」の部分は、
別にプロシージャを作成して、各イベントプロシージャから呼び出すようにすれば合理化できます。

CheckBox7がTrueになった直後は、8〜11のうちどれをTrueにするのか、とか、
8〜11のうち既にTrueになっているものがClickされたらどうするのか、などの点が
はっきりしませんが、方針さえ決めてしまえば簡単に修正できるはずです。


906 :デフォルトの名無しさん:2008/08/20(水) 18:53:18
こいつの口調、癇に障る。
ただそれだけで、消えてほしいと願う。

907 :デフォルトの名無しさん:2008/08/20(水) 19:57:47
お前が消えればいいじゃん

908 :デフォルトの名無しさん:2008/08/20(水) 20:50:56
>>906
お前の方が癇に障って癪だわ。お前が消えろ。

909 :デフォルトの名無しさん:2008/08/20(水) 21:22:01
自作自演ヒドス

910 :デフォルトの名無しさん:2008/08/20(水) 23:10:50
匿名掲示板でコテハンを長く名乗るって事は、それだけのリスクがあると言う事。
自分の向学の為ならば、コテを名乗る必要はどこにもない。

仮に間違った事を回答したとしても、責任なんてない。逃げるのも簡単。
それが匿名掲示板だから。

自分で退路を塞ぐだけでも愚かな事なり。

911 :デフォルトの名無しさん:2008/08/20(水) 23:27:26
そんなのどうでもいいわ。ここはExcel VBAのスレだろ

912 :デフォルトの名無しさん:2008/08/20(水) 23:27:31
コテハンがそんな大層なもんかね
何か勘違いしてるんじゃないの

913 :デフォルトの名無しさん:2008/08/20(水) 23:45:02
退路っていうのは間違っても訂正しないことなんだろうか

914 :デフォルトの名無しさん:2008/08/20(水) 23:47:48
荒れてますな〜w

915 :デフォルトの名無しさん:2008/08/20(水) 23:49:41
>>914
マクロだけにねプッ

916 :デフォルトの名無しさん:2008/08/21(木) 08:41:58
>>905

ありがとうございます。助かりました。

917 :デフォルトの名無しさん:2008/08/21(木) 21:14:17
すんません。質問させてください。

違う部署の人にヘルプを頼みまして、条件に合致する物にフラグを立ててくれたんです。
後で処理するんで、文字列の最後尾に記号をくっつけといてもらったのですが、
よりによって、アスタリスクが最後尾に付いてました。

適切に指示しなかった私が悪いと思い、今後は別の記号か、
別のセルに数字でフラグを立ててもらう事にしたのですが、
そこで質問です・・・。

autofilterも、replaceも、*はワイルドマークとして機能しているようですが、
エスケープシーケンスは存在しますでしょうか。
文字列としての*を判定させたい場合の処理などが可能でしたら教えてください。


918 :デフォルトの名無しさん:2008/08/21(木) 21:22:29
[*]

919 :デフォルトの名無しさん:2008/08/21(木) 21:43:27
ありがとうー

920 :デフォルトの名無しさん:2008/08/21(木) 21:59:10
質問です。
他のxlsファイルを読み込んでいろいろ作業するのを、マクロの記録からやると
切り替えごとにWindows("hoge.xls").Activateになりますよね?
これだとファイル名を変えると動かなくなるのでなんとかしたいのですが
元の方はThisworkbook.Activateに置き換えすると済みますが
相手ファイルも同様に使いやすくするにはどうしてますか?

GetOpenFileで指定したファイルをどこかの非表示セルに書き込んで
それを読み込む方法しかないのでしょうか?
他にいい保存場所ないのかなぁ?

921 :デフォルトの名無しさん:2008/08/21(木) 22:14:15
起動中のエクセルファイルには、起動順に番号が割り当てられている。
ファイル名を指定しなくても、
Workbooks(n).Activate
(nは数字)という形で、n番目に開いたファイルをアクティブにできる


922 :デフォルトの名無しさん:2008/08/21(木) 22:16:17
一時的にマクロを停止させ、
その間にワークシートを操作するプログラムを組みたいのですが躓いています。

waitメソッドを使えば実現できるかと思ったのですが、
マクロは停止するけれどもワークシートが操作不可能です。

実現するべく何が良い方法があればご教授ください。

923 :デフォルトの名無しさん:2008/08/21(木) 22:18:11
doevents

924 :デフォルトの名無しさん:2008/08/21(木) 22:25:07
>>920
hoge=Activexworkbook.nameで開いたファイル名を取得

925 :デフォルトの名無しさん:2008/08/21(木) 22:25:33
コントロール配列使えないVBAももうちょっと頑張ってくれればいいのにな。
vbe.netとかつくって欲しい。

926 :920:2008/08/21(木) 22:32:10
>>924
それだと毎回ダイアログ画面で指定しなきゃいけませんよね?
ファイル名を変えちゃったときに、一度指定してもらうだけで済ませたいのです。

927 :y:2008/08/21(木) 22:48:28
>>926
非表示セルか非表示シートのセルでいいのでは。
個人用マクロブックとか、外部テキストファイルとか、いろいろ考えられますが、
複雑になるだけだと思うので。


928 :デフォルトの名無しさん:2008/08/21(木) 23:30:45
総合スレよりこっちの方が良さそうなのでこちらで質問します。
ワークシート上に配置したコンボボックス(フォームではなくActiveXの)に初期値として、
今日から5日前〜今日から10日後の日付をセットしたいのですが、うまくいきません。
ユーザーフォームだとUserform_Initializeの中に記述すればいいんですが、
同じ様にはできません。どうすれば良いでしょうか。
clickイベントでも試しましたがコンボボックスはchangeイベントしかダメなのかな?

929 :デフォルトの名無しさん:2008/08/22(金) 02:32:27
>>928
UserformにはUserformのイベントがあり、ThisWorkbookにもイベントがある。
Private Sub Workbook_Open()
For i = 4 To 0 Step -1
Sheet1.ComboBox1.AddItem Date - i, 4 - i
Next
Sheet1.ComboBox1.ListIndex = 0
End Sub


930 :928:2008/08/22(金) 07:23:05
>>929
そっか、ブックを開いた時にイベント発生させれば良かったのか。
ありがとうございました。

931 :デフォルトの名無しさん:2008/08/23(土) 03:58:17
相対参照を含む数式を位置関係を考慮してずらしてコピーする方法はありますでしょうか
コピー元C5セル:=B5
コピー先C10セル:=B10
のようにコピーしたいのですが
Range(C10).formula=Range(C5).formula
のようにするとC10が=B5になってしまいます。
調べてもFillDownというものしか出てこず離れたところにコピーするやり方が分かりません。
すみませんがご存知の方教えていただけないでしょうか

932 :デフォルトの名無しさん:2008/08/23(土) 06:33:53
>>931
Range("C10").FormulaR1C1 = Range("C5").FormulaR1C1

933 :デフォルトの名無しさん:2008/08/23(土) 14:03:39
>>932
ありがとうございます
意図したことが出来ました


934 :デフォルトの名無しさん:2008/08/23(土) 15:59:51
VBA使って関数や数式のコピーってどうなのよ。
モジュールに数式書いてくれればすぐわかるのに、
数式のコピーって、いちいちプロパティで調べないといけないから面倒なんだけど。

なんでそんな事するの?死ぬの?

935 :デフォルトの名無しさん:2008/08/23(土) 16:14:09
>>934
あなたは13日後にしにます

936 :デフォルトの名無しさん:2008/08/23(土) 17:40:05
呪殺予告きたー!
これは逮捕だな

937 :デフォルトの名無しさん:2008/08/23(土) 21:27:46
>>934の言っている意味がわからない。
数式コピーされると死ぬの?呪殺されちゃうの?

938 :デフォルトの名無しさん:2008/08/23(土) 21:53:17
なれないVBAで苦労しているのですが、オートシェイプ周りの制御はどうすれば
良いんでしょうか。移動や変形どころか、アクセス方法すら分からずじまいで。

取っ掛かりだけで十分なので、教えていただければ幸いであります。
流れ読まずにすまんですたい。

939 :デフォルトの名無しさん:2008/08/23(土) 22:00:01
なにがしたいの?

940 :側近中の側近 ◆0351148456 :2008/08/23(土) 22:09:37
>>938
(っ´▽`)っ
マクロの記録でやってみればいいじゃん

941 :デフォルトの名無しさん:2008/08/23(土) 22:20:50
>>939
「頂点の編集」がグリッド無視するのをどうにかしたり、直線を他のオートシェイプに置換できないかなと。

>>940
あーなるほどこんな手が。取っ掛かりが掴めました。ありがとうございます。

942 :側近中の側近 ◆0351148456 :2008/08/23(土) 22:27:25
(っ´▽`)っ
テンプレに
わからなければ、とりあえず「マクロの記録」をやってみましょう
がないことに驚き☆

943 :デフォルトの名無しさん:2008/08/23(土) 22:33:10
Excell2007でVBAでプログラム組んで動かしたんだけど
かなり実行に時間がかかってしまう・・・

今のパソコンはC2Dの2.4Gでメモリ2GでXP何だけど
ハードを新しくするのとOSをVistaにするのどっちが効果的ですか?

944 :デフォルトの名無しさん:2008/08/23(土) 22:34:16
真逆の選択肢に見えるのが面白いw

945 :デフォルトの名無しさん:2008/08/23(土) 22:39:42
>>943
64bit Vistaにしたまえ

946 :y:2008/08/23(土) 22:50:05
>>943
もうご存知かもしれませんが、>>724もとりあえず参考までに。



947 :デフォルトの名無しさん:2008/08/23(土) 22:50:45
>>934
出来てありがとうって言ってるのにその追い討ちはわけがわかりませんww
数式コピーできなくても死にはしませんよ
VBAに書くと柔軟性が失われるから外出しにしておきたいのです。
再利用性を高めるのに最も良い方法は命令をコマンドにすることです。数式に限らずSQLなどの柔軟性の高い命令は外出しが良いのです。

948 :デフォルトの名無しさん:2008/08/23(土) 22:52:21
リストボックスで複数選択した分だけ
H列の11行目から4行ずつ下へオートフィルを使ったコピーで展開したいんだけど、
コードがうまく思いつかなくて四苦八苦してます。


リストから複数選択した分をjに入れたとして、
コードは
Range("H7:H10").AutoFill Destination:=Range("H7:H10+j")


としたけど中々コードが思いつかずわかりません・・・
VBA始めて2週間、本やネットで検索してもリストボックスの扱いがあまりなく苦労してます。

949 :側近中の側近 ◆0351148456 :2008/08/23(土) 22:55:51
>>947
(っ´▽`)っ
それだったら、数式をConst String型にしておいたほうがいいよ☆
数式のコピーよりも分かりやすいような気がする。
数式のコピーだと、>>934のように、数式がソース上どこにも出てこないことになるから。

950 :デフォルトの名無しさん:2008/08/23(土) 22:59:06
>>943
スレ違いだけど
チューニングという選択がいいと思うよ
まずは使い終わった計算式を削除してみること

951 :側近中の側近 ◆0351148456 :2008/08/23(土) 22:59:11
(っ´▽`)っ?
>柔軟性の高い命令
今気づいた。動的に数式が変わるっていうこと?
それだとConstじゃダメだね。

952 :側近中の側近 ◆0351148456 :2008/08/23(土) 23:01:30
>>943
(っ´▽`)っ
「マクロの記録」で生成されたプログラムだと、
.selectが多くできるけど、これを無くすとかね。
range("A1").select
selection.value = 1

range("A1").value = 1

953 :側近中の側近 ◆0351148456 :2008/08/23(土) 23:20:09
>>948
(っ´▽`)っ ほ〜れほ〜れ☆
Range(Cells(7, 8), Cells(10, 8)).AutoFill Destination:=Range(Cells(7, 8), Cells(10 + j * 4, 8))

954 :デフォルトの名無しさん:2008/08/23(土) 23:21:37
>>951
動的には変えませんが、数式はユーザに変えてもらうカスタマイズポイントです

955 :側近中の側近 ◆0351148456 :2008/08/23(土) 23:30:25
>>954
(っ´▽`)っ
ほうほう。
じゃあ、セルに名前をつけて、それでアクセスするといいかも。
Range("C10").FormulaR1C1 = Range("C5").FormulaR1C1
これだと、C5ってなんだ?ってことになる。ソース上はわからない。
ワークシートのC5を見ればわかるけどね。
たとえば、セルC5に"カスタマイズSQL"という名前を付ければ
Range("C10").FormulaR1C1 = Range("カスタマイズSQL1").FormulaR1C1
と書くことができる。
ソース上もわかりやすくなってイイ!>>934の不安も払拭される。

セルの名前は「挿入」→「名前」→「定義」で設定できるよ☆

956 :側近中の側近 ◆0351148456 :2008/08/23(土) 23:31:13
(っ´▽`)っ
間違えた☆

たとえば、セルC5に"カスタマイズSQL"という名前を付ければ
Range("C10").FormulaR1C1 = Range("カスタマイズSQL").FormulaR1C1
と書くことができる。

957 :948:2008/08/23(土) 23:32:54
>>953
できた!サンキューです♪
胸のつっかえが取れました(o^-')b

Rangeじゃ駄目だったんですね。
これで次の勉強に進められます。

ありがとうございますヾ(o゚∀゚)ノ゛

958 :デフォルトの名無しさん:2008/08/24(日) 00:23:56
VBAで課長の背骨をヘシ折る事は可能?
あと、栗とか剥ける?VBAで。

ググッても全然HITしない。

959 :デフォルトの名無しさん:2008/08/24(日) 00:33:29
ああ、できるよ。

960 :デフォルトの名無しさん:2008/08/24(日) 00:59:57
>>956
ありがとう
一応名前付き範囲は知ってるよ
君はのりのりですごい親切だね
また今度教えてね

961 :デフォルトの名無しさん:2008/08/24(日) 01:06:38
うぜーよ

962 :デフォルトの名無しさん:2008/08/24(日) 01:35:44
>>959

うっそマジ?
じゃあ例えば

Sub 課長()

Dim 課長 As Integer
Dim ボディ As Boolean
Dim 吐血 As Integer

課長 = 1
吐血 = 101


Do Until 課長 = 吐血

If Cells(課長, 1) = "" Then
ボディ = True
課長 = 課長 + 1
End If

Loop

MsgBox "課長は吐血しました。もうやめて下さい。"

End Sub

とかで課長吐血する?VBAで吐血する?

963 :デフォルトの名無しさん:2008/08/24(日) 01:46:31
そのコードじゃ無理だけどな

964 :デフォルトの名無しさん:2008/08/24(日) 09:10:49
VBAでルーチン組んでから、椅子で殴れば良いじゃん。

965 :デフォルトの名無しさん:2008/08/24(日) 10:12:58
ハードディスクのデータをクリーンにするプログラムを組んでプレゼントしなさい。

966 :デフォルトの名無しさん:2008/08/24(日) 10:20:17
VBAでできるけどスレ違い。Excel関係ないから。

967 :デフォルトの名無しさん:2008/08/24(日) 10:52:44
2003です。
マクロの記録からオートシェイプをやったけど
そのまま実行すると塗りつぶし無しだけがキャンセルされてしまいます。

ActiveSheet.Shapes.AddShape(msoShapeOval, 257.25, 109.5, 39.75, 21.75).Select
Selection.ShapeRange.Fill.Visible = msoFalse
Selection.ShapeRange.Fill.Solid
Selection.ShapeRange.Fill.Transparency = 0#
Selection.ShapeRange.Line.Weight = 1.5
Selection.ShapeRange.Line.DashStyle = msoLineSolid
Selection.ShapeRange.Line.Style = msoLineSingle
Selection.ShapeRange.Line.Transparency = 0#
Selection.ShapeRange.Line.Visible = msoTrue
Selection.ShapeRange.Line.ForeColor.SchemeColor = 64
Selection.ShapeRange.Line.BackColor.RGB = RGB(255, 255, 255)
どうすれば塗りつぶし無しに出来ますか?


968 :側近中の側近 ◆0351148456 :2008/08/24(日) 11:07:37
>>967
(っ´▽`)っ
Selection.ShapeRange.Fill.Solid
を削除しましょう。

969 :デフォルトの名無しさん:2008/08/24(日) 11:52:21
>>968
ありがとうございます

970 :デフォルトの名無しさん:2008/08/24(日) 14:41:12
CSVファイルの数値を分析したいのですが
フォルダ内すべてのCSVファイルにマクロを実行する方法はありますか?

紹介されている本やHPを教えていただけませんでしょうか?

よろしくお願いします。

971 :デフォルトの名無しさん:2008/08/24(日) 20:17:55
うーむ・・・CSVってカンマ区切りのデータテキストの事だよね?
一度EXCELに読み込んで処理じゃダメなのかな。

972 :デフォルトの名無しさん:2008/08/24(日) 20:51:32
このスレ的にはそれがいいね。
どうやってやるかは、マクロ記録すればすぐ判ることだし。

973 :デフォルトの名無しさん:2008/08/24(日) 21:59:24
excelで普通によみこむと、おもってるのと違う動きされることあるんだよなー。
だから、俺は、1行ずつ読み込み、コンマで区切りごとのデータを自前で配列にいれる
多バイト文字つかわれてたりするとこは、1フィールドごとにエンコードチェック、
をずっとEOFまでやってから、自分のおもってる型にかえてから処理しとる。

974 :y:2008/08/24(日) 22:14:08
「フォルダ内すべての」CSVファイルに対して処理をしたい、
という点でもつまずいているのかも。それについては、
「FSO」を検索すると役立つ情報が見つかると思います。


975 :デフォルトの名無しさん:2008/08/24(日) 23:17:58
CSVの定義って厳格な物ある?ファイル形式とか。
気になって調べたんだけど、ファイル形式までは規格されてないような。

んで、フォルダの中身全部、って指定がかなり難しいのではないかなと。
たとえば拡張子がtxtだとしても、それがCSVで組まれたデータファイルなのかは、
計算機で判断出来るの?って思ってさ。

976 :デフォルトの名無しさん:2008/08/24(日) 23:37:56
>>974
先にDir勧めろ。

>>975
RFC4180というものがあるにはある。

977 :デフォルトの名無しさん:2008/08/24(日) 23:38:05
RFC 4180

978 :デフォルトの名無しさん:2008/08/24(日) 23:54:22
基本的に、顧客が好むのが、Excelでひらいたときにどうみえるか。
なんで、
"dataA", "dataB", ... , "dataX"
みたいに、""でかこむことになる。
数値解析とかだけのローカル用途なら、囲まんけどな。

979 :デフォルトの名無しさん:2008/08/25(月) 00:04:47
FSOの.Filesでファイル一覧取得して、Right$で.csvだったら、
FSOの.Readallで読み込んで、VBCRLFでSplitして、
配列に入れて配列をカンマで、Split

980 :デフォルトの名無しさん:2008/08/25(月) 00:09:35
プロジェクトのこまごま作業で多かったのがFSOによる再帰ファイル検索だ

981 :デフォルトの名無しさん:2008/08/25(月) 00:14:27
"abc,def","ghi",""""
ってな感じのデータに対応しようと思ったら面倒よ、自前でやるのは

982 :デフォルトの名無しさん:2008/08/25(月) 02:00:47
FSOでやるなら普通にGetExtensionNameでcsvかどうかを見ればいいんでね?

983 :y:2008/08/25(月) 19:17:14
>>976
あ、そっちの方が簡単かも...
オブジェクト作らないで済みますし。

Const fPath = "(フォルダのパス)"
Dim fName As String
fName = Dir(fPath, vbNormal)
Do While fName <> ""
 If UCase(fName) Like "*.CSV" Then
  'Open 〜
  '>>979の後半みたいな処理
  'Close 〜
 End If
 fName = Dir
Loop

こんなやり方でいいのかな。
CSVデータは、シングルクォーテーション('')で囲まれたタイプのも
ざらにあるので意外と厄介ですよね。

984 :デフォルトの名無しさん:2008/08/25(月) 20:21:21
Dir(fPath & "\*.csv", vbNormal)
Ifはいらない

985 :デフォルトの名無しさん:2008/08/25(月) 20:28:40
FSOとかつかうと
2008/08/25 20:27:30
みたいなフィールドがtextstream通した時点で
2008/08/25 20:27
とかされるからやめたほうがいいぞ。他にも罠多数。

どうしてもVBAっちゅーんなら、バイナリで読み込んで処理。これしかない。
自作のあるけど、バグあるとはずかしいから公開できん。
結構、考慮するべきパターンあるんで、かなり大きい。

986 :側近中の側近 ◆0351148456 :2008/08/25(月) 20:47:47
(っ´▽`)っ
もし作るのが業務ソフトウェアなら、許容するCSVの仕様ぐらい決めたら?
こういう感じに。ちなみにこれはExcelのCSVの仕様に準じている。

・カンマ区切り
・ダブルクォーテーション内のカンマは区切りとみなさない。
・二連続のダブルクォーテーションは、文字としてのダブルクォーテーションと見なす。
(項目にダブルクォーテーションを含めたい場合には、ダブルクォーテーションを2つ打つこと)
・閉じていないダブルクォーテーションはエラー。

入出力は過剰だと思うぐらい明確にしたほうがいい。

987 :側近中の側近 ◆0351148456 :2008/08/25(月) 20:50:39
(っ´▽`)っ
>>986に追加。

項目にカンマを含めたければ、ダブルクォーテーションで項目を囲うこと。
(例:"1,000","12,000")

988 :967:2008/08/25(月) 20:52:23
ActiveSheet.Shapes.AddShape(msoShapeOval, 257.25, 109.5, 39.75, 21.75).Select
Selection.ShapeRange.Fill.Visible = msoFalse
Selection.ShapeRange.Fill.Transparency = 0#
Selection.ShapeRange.Line.Weight = 1.5
Selection.ShapeRange.Line.DashStyle = msoLineSolid
Selection.ShapeRange.Line.Style = msoLineSingle
Selection.ShapeRange.Line.Transparency = 0#
Selection.ShapeRange.Line.Visible = msoTrue
Selection.ShapeRange.Line.ForeColor.SchemeColor = 64

これで2003でうまく塗り潰しの無い輪っかが描けたので
会社の2007に組み込んだんだけど、今度は黒塗り潰しに化けてしまいました・・・・
急遽マクロの記録で輪っかを描いてみたものの、なんと2007では図の挿入あたりの記録はしてくれないようです・・・。
互換性が無いのもむかつくが、マクロ記録も改悪されてるとは実に情けない話と思います。

どなたか、黒丸で中塗り潰しの無い輪っかを2007で実現してくれるコードを教えてください。

989 :デフォルトの名無しさん:2008/08/25(月) 21:04:19
マクロの自動記録でいいんじゃないの

990 :デフォルトの名無しさん:2008/08/25(月) 21:10:10
CSV仕様きめても精確な実装はなかなかむずかしい。
もうほんと想定外の入力がされてたりする。

特に業務でよくあるのが複数行にわたって改行つきのコメントフィールドとか
SJISとはかぎらんわけで、難しい。

もうこれでいいだろ、とおもうくらい慎重に実装しても、おれの技術じゃ
100万件のフィールドよむと、たいてい2,3件は、バグにかかる。
で、そっから、その特殊なケースをADHOCに直していくという対応。
例外でたからあとから3件追加しますとか、じゃ納得してくれんし、3年後に
でるかもしれないわけで。。。ほんと怖いよ。

一番いいのは、EXCELでCSVをよみこむのはあきらめることじゃ。。。


991 :967:2008/08/25(月) 21:15:57
>>989
2007ではマクロの記録をしても、オートシェイプの挿入〜線種変更などをなにも記録してくれないのです。

992 :側近中の側近 ◆0351148456 :2008/08/25(月) 21:16:40
>>991
(っ´▽`)っ
ウォッチウィンドウでそれっぽいプロパティを探せ☆

993 :デフォルトの名無しさん:2008/08/25(月) 21:54:19
>>991
2007で普通に記録できたよ。
ついでに貼っておきますね。

ActiveSheetのオートシェイプを赤にするコード。

Dim sp As Shape
For Each sp In ActiveSheet.Shapes
With sp
sp.Fill.Visible = msoTrue
sp.Fill.Solid
sp.Fill.ForeColor.SchemeColor = 10
sp.Fill.Transparency = 0#
sp.Line.Weight = 0.75
sp.Line.DashStyle = msoLineSolid
sp.Line.Style = msoLineSingle
sp.Line.Transparency = 0#
sp.Line.Visible = msoTrue
sp.Line.ForeColor.SchemeColor = 64
sp.Line.BackColor.RGB = RGB(255, 255, 255)
End With
Next



994 :デフォルトの名無しさん:2008/08/25(月) 22:03:21
これで透明になるよ
For Each sp In ActiveSheet.Shapes
sp.Fill.Visible = msoFalse
Next


995 :デフォルトの名無しさん:2008/08/25(月) 22:44:49
999-9999-9999や9999-99-9999の書式で入力された電話番号を
(999)-9999-9999や(9999)-99-9999の書式にしたいのですが
A=Range("A1").Value
B=Find("-",A,1) -の位置
C=Left(A,B-1)    -の前だけ抽出
D=Mid(A,B,Len(A)-B+1) -の後ろを抽出

求める文字列="(" & C & ")" & D

関数だとこんな感じだけど、VBAではどうやりますか?



996 :デフォルトの名無しさん:2008/08/25(月) 22:45:45
うちはXMLに統一してるんでCSV時代のトラブルは一切無くなったな。

997 :デフォルトの名無しさん:2008/08/25(月) 22:46:41
>>995
InStr

998 :y:2008/08/25(月) 22:57:06
>>984
ありがとうございます。大文字・小文字を考えなくて済むのでますます楽です。

>>985
まさかそんな罠があるとは...。自分でも実験してみます。

999 :デフォルトの名無しさん:2008/08/25(月) 22:59:46
ume

1000 :デフォルトの名無しさん:2008/08/25(月) 23:01:54
1000

1001 :1001:Over 1000 Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。

337 KB
★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)