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
3 :
デフォルトの名無しさん :2008/06/04(水) 23:00:00
早速ですが エクセルでVBAの プログラムで001.csv-999.csvまでのCSVファイルを順に読んでアクセスDBに 入れたいのだが まず変数 csvnameでCSVファイルを読み込むにはどうすればいいのですか?
Accessでやれ。 はい、次。
どうやったら彼女が出来ますか?
>>5 VBAを習得してからの私はそれはもうモテモテです
>>4 エクセルでのやり方が解らないからって代替を強制すんな無能
>>7 >>4 ではないが、この要件にExcelをかます意味ある?
ExcelVBAが得意な人がわざわざExcelVBAでやるならわかるけど、
ExcelVBAが使えないならAccessVBAなりVBなりの質問掲示板で質問するべきでは?
>>8 バカじゃねえのか?
エクセルVBAでって指定してんだから、意味なんかお前が勝手に判断すんなボケ
10 :
デフォルトの名無しさん :2008/06/05(木) 18:22:48
アクセスって立ち上げるの面倒くさい。
>>8 まぁまぁ、そんなイライラせずに仲良くやろうよ(^^
そんで、なんでわざわざExcelVBAを使いたいんだーい?
全スレ
>>998 ありがとうございました。 パターン 「.*?」 の正規表現ですっきりできました。
13 :
3 :2008/06/05(木) 19:05:53
自己解決しました。
チェックボックスをONにしたらOffset(0,10)に"1"を入れる方法教えて下さい
15 :
14 :2008/06/05(木) 19:46:24
できたからいいわw
16 :
デフォルトの名無しさん :2008/06/05(木) 20:20:32
ExcelVBAで、g解決しました。
教えてください・・ エクセルVBAで質問です 二次元配列で例えば、ab(a、1)=10だとして 変数wk-hensuに、1が入っていたとします wk-hensuの1を使って二次元配列の10の値を 取得したいのですが、どうすればよろしいですか?
さっぱり意味がわからない
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%) オブジェクトがはいらん。なんで? なにがいけないのか?
>>23 そうだね
ab(a、wk-hensu)=10 じゃなくて
新しい変数=ab(a、wk-hensu) だね
26 :
デフォルトの名無しさん :2008/06/07(土) 08:25:59
コレクションがよくわからん。
最近、VBも使うようにしてるので、オブジェクトSetも努力しているんだが、
たとえばこの
>>21 のケースのように、
sheetsを特定して格納したい、workbookを特定して格納したい、
ってときはどんなオブジェクトを宣言すればよろしい?
rangeオブジェクトのときは、cell範囲指定すれば入ることはわかるがどーちがうのかな・・
頼むヒントを
いや、ヘルプ見ろよ
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")
ってカンジ
普通はこっち
セルのA1からA10と、B1からB10に数値が入っています これをgolf(9,9)配列に入れたい場合はどうすればいいですか? 初心者なのでよくわかりません。お願いします
>>31 >golf(9,9)
10×10=100要素あるけど、どこに入れたいの?
dim golf() as variant
golf()=range("A1","B10").value
って方法もあるよ
>>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列)を
代入できることは可能ですか?
>>33 dim i as long
for i=0 to 9
golf(0,i)=cells(i+1,"C").value
next i
>>34 インデックスが有効範囲にありませんとでますが
どうしたらいいでしょうか?
golf(0,i)=cells(i+1,3).value かな
"C"でも行けるよ golfをちゃんとdimしてないんだろ
39 :
38 :2008/06/07(土) 19:55:13
おっとすまんかぶった
40 :
35 :2008/06/07(土) 20:00:22
golfはdim golf() as variantと宣言しています・・・
うん、それじゃダメだね
>>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 でいいのでしょうか。
やってみれば済む話だろう
47 :
45 :2008/06/08(日) 11:31:11
それが、最近も出来ていたと思うんですが、今回、コンパイルエラーで跳ねられた。 !の所をさして、修正候補 又は( という具合で。 どうも、文法的に勘違いをしていたようなので、訊いてみました。 現実には、.runで解決済みですが。
49 :
デフォルトの名無しさん :2008/06/08(日) 22:06:40
超くだらねーことかもしれんが、適当な変数宣言の一般的な名称ってどんなもんがあるかね? @たとえば、インテジャーなら? Aロングなら何使う? Bレンジなら? Cワークシートなら? Dブーリアンなら? 俺は考えるのが面倒だからすぐバカみたいな変数宣言するので とても人に見せれん。 TAROU UNKO MANKO DEVILMAN RAOU KENSIROU とかよ。 数年たっても自分のクセなんで、クチャクチャな宣言でも自分はわかるんだよね、これが。
>>49 型はさておき、その変数が指すものを表現する名前がいいんじゃないか。
太郎くんのことを表現したいのならTAROUでも差し支えないと思う。
個人オンリーのものなら好き勝手に 会社とかで、んな変数名にしていやがったら、張り倒すけどな。
一般的な変数名なんてループに使うi、j、kくらいだべ
TZEF2101 CMED9301
54 :
デフォルトの名無しさん :2008/06/09(月) 23:08:23
>>51 当然会社のやつ。俺以外はVBAの変数を理解しているやつがいないからやっちまった。
>>52 ループでそれらの変数は使うのかな?
俺の場合、ループの時はインテジャなら大体a%,b%とかで適当に回す。
なんかだれがみてもわかるような変数や構文のコツがあるかな。
たとえばプライベートサブやらを Callするときは必ず全角文字を使うとか、コメントをつけまくるってクセは付けてる。
ループは俺もi、j、k、l、Index、この辺だな てか会社でそんなあほなことは絶対にやめておけ どんな業種か知らんがたいてい知らん振りしてるだけでけっこう知ってる人はいるもんだ
VBAをかなり理解してるやつ(ステートメント、条件式、階層の完全理解くらい)とか身近な人間でいる? 会社とか大きな組織とか行くと多少のVBAプログラムされているものは見るが、 バグの固まりみたいなもので、共有して使っているのが不思議なものしかみたことない。 手順書すらなくて、非常に困る。 俺的にはこんなものはプログラムではない、と思うんだが、そんなこと偉そうに言える立場ではないので 我慢してヒマを見てはコードを改造しているが、似たような境遇の人はいないかい?
57 :
デフォルトの名無しさん :2008/06/09(月) 23:21:20
>>55 以後気をつけます。 しっかし、変数名考えるのめんどくせぇーなー。
ところで、自分はあんまりやったことないんだが、↓
dim I(100) as Long
↑これってインデックス付きの変数Iを100個宣言してるんだよね?
で、代入するときは
I(1)=1
I(2)=5 とかで。
この番号ふった大量の変数Iを活用するには当然ループさせるときに効果を発揮すると思うんだが、
俺を相手してくれる暇人が居るならば、具体的になんか適当なコードを書いてみせてくれんかな?
Dim i(1 to 10) As Integer とか俺はけっこう使うぞ
配列を効率的に使いこなせるようになったら脱VBA初心者 と、個人的に思ってる やっとこのレベルあたりで独力で多少役に立つモノ作れるようになるんじゃない?
マスタのシートの表で0という値が入力された場合に 特定のシートを非表示にさせるには どのようにすればよろしいのでしょうか?
>>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 はスゲーと思う。
俺なんて適当でも、ハンガリアン表記?ってやつの呪縛から逃れられない。
かといって、確実に誰でもわかるかっていったらどうなのか微妙な中途半端さ
何にもないところからデビルマンとかケンシロウが出てくるお前ってスゲーな。
RPGのキャラの名前はデフォのままってタイプだな
>>64 は
変数名とか普通に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を行っております。 この方法について、何か最適化の手立てはありますでしょうか。 なにとぞご教授をよろしくお願いします。
>>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日に なります。
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)
のような形で連結させる事ができました。
本当にありがとうございます。
>>68 まさかループしながら&演算子で連結しろって言ってないよな?
>>75 勿論そのつもり
何でまさかなのかわからん
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 ここまで書いて挫折しそうです。どなたかアドバイスをいただけませんか?
>>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
ユーザフォームを表示したいので、以下のようにやったのですが、エラーになります。 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の場合、どうやってユーザフォームを表示するのが正しいのですか??
>>78 さんありがとうございます。
参考にさせていただきます。
>>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
>>82 >Cells(i, .Value
コレは何を意味してんの?
>>81 ありがとうございます。
UserForm1は型であるという私の考え方が間違っていて、
UserForm1は型であり、オブジェクトのインスタンスであると考えるのがVBAなのでしょうか?
(どうせシングルスレッドだし、複数のインスタンスは作れないから?)
うーーーーん
VBAムズカシイ
85 :
84 :2008/06/12(木) 01:27:10
とおもったけどやっぱり同じエラーが。 よく見たらUserForm1.Initializeで変な記述してたのが原因でした。
>>84 いや、VBAのUserFormは特別扱いだと思う
難しく考えると腹立つと思うよ
インスタンスという考え自体を意識しないでいいように設計されているんだと思う
VBA使いの98%(単なるオレの偏見)はインスタンスが何かも理解してない上に
インスタンスという言葉さえ知らないと思う
New すれば複数のインスタンスも作れるんじゃないかな?(未確認)
あくまでも、個人的な見解です
>>85 VBEの ツール - オプション - 全般 - エラートラップ を クラスモジュールで中断
にチェックすると幸せになれるよ
>>86 なるほど。わかりました!深く考えないことにします
>>87 早速やってみます。ありがとうございました
89 :
デフォルトの名無しさん :2008/06/12(木) 07:08:00
>>82 です
なんかコピペしたら消えてました・・・
>Cells(i, 8).Value です
要件をはっきりさせましょう。 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稼働日後を出したらよいのか…ちなみにアドイン関数は無いので使えません…よろしくお願いいたします。
稼働日に連番を振るのがいちばん簡単だな
93 :
デフォルトの名無しさん :2008/06/12(木) 12:32:15
回答ありがとうございます。 すみません。連番をふるとはどういうことでしょうか?初心者なので検討がつきません…
つまりだな 日付 休日 連番 4/1 1 4/2 2 4/3 休 4/4 3 4/5 4 こんな感じ。4/1の3稼働日後は1+3=4だから連番が4の4/5になる
印刷しようとする時にそのシートに"菓子"という言葉が無かったら印刷せず、 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のような固定ではないのかな? 何をしたいのかがイマイチよくわからない。
なんつーか・・・ いい加減にしろ
すいません95ですがホント教えてくれ
>>99 | ̄``''- 、
| `゙''ー- 、 ________
| ,. -‐ ''´ ̄ ̄`ヽ、_ /
|, - '´ ̄ `ヽ、 /
/ `ヽ、ヽ /
_/ ヽヽ/
/ / / / / / ヽハ
く / /! | 〃 _/__ l| | | | | | | ||ヽ
\l// / | /|'´ ∧ || | |ー、|| | | l | ヽ
/ハ/ | | ヽ/ ヽ | ヽ | || /|ヽ/! |/ | ヽ
/ | ||ヽ { ,r===、 \| _!V |// // .! |
| || |l |ヽ!'´ ̄`゙ , ==ミ、 /イ川 |─┘
| ハ|| || | """ ┌---┐ ` / // |
V !ヽ ト! ヽ、 | ! / //| /
ヽ! \ハ` 、 ヽ、__ノ ,.イ/ // | /
┌/)/)/)/)/)/)/)/)/)/)lー/ ` ー‐┬ '´ レ//l/ |/
|(/(/(/(/(/(/(/(/(/(/│|| |\ 〃
r'´ ̄ヽ. | | ト / \
/  ̄`ア | | | ⌒/ 入
〉  ̄二) 知ってるが | | | / // ヽ
〈! ,. -' | | ヽ∠-----', '´ ',
| \| | .お前の態度が | |<二Z二 ̄ / ',
| | | _r'---| [ ``ヽ、 ',
| | | 気に入らない >-、__ [ ヽ !
\.| l. ヽ、 [ ヽ |
ヽ| \ r' ヽ、 |
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
>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だった。 もう寝る。
>>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でも入れて見ようかと思ってたとこでした。
>>111 言ってることはわかるが、コードのエレガントさを取るか
0コンマ0何秒を惜しむかの個人の好みの問題かと
> 普通は&演算子で連結しない。
コレは無い。普通にやる
>コレは無い。普通にやる ダメだこりゃ。
>>111 なるほど、俺も最初はわからなかったがそういうことか。言語が内部でどう処理するか考えてるつもりだったが…
メモリ確保のことまで考えてなかった、教えてくれてありがとう。ループのときは気をつけよう。
VBAのスレなのに言語の仕組みとか機械語とか知ってる人がいるとは…
うかつなこと書き込めないな。ちなみに今回この板の初書き込み。
>>115 いや、時間がかかるってのは確かだし認めるよ
しかし、実測してみたが100文字を100回(計1万文字)を1万回試行して差は5秒程度
100文字を100回連結しても差は1万分の5秒(0.5ms)だよ
この為に格納用の配列変数を要素分確保して、Excel2000(Excel2002?)から採用のJoin関数を使うのと、
文字列変数を1つ用意してループで直接連結して最初(又は最後)の余計な連結記号を削除するのは、
どちらが正解って問題なのかな?
Excelのマクロごときでそんな細かい事を気にする奴は神経症
119 :
デフォルトの名無しさん :2008/06/13(金) 21:14:19
Textボックスにフォーカスがあたったときに、 あるTextボックスの場合は日本語入力をONにして、 別のTextボックスの場合は日本語入力をOFFにしたいのですが、 そういう制御は可能ですか?
>>120 Excel2000以降ならJoin関数が簡単だし、それより前のバージョンならMidステートメントがデフォ
VBAで作成したファイルが、エクセル終了しないと開けませんorz 拡張子がtxtだと開けるのですが・・・
>>121 は、たとえばA1:A50000に各6文字あるデータを","で連結してみりゃ&演算子がいかに遅いかわかる。
1文字の区切り文字での連結なら
>>124 が書いてるMidステートメントが最速で、次がString型の一次元配列に格納しなおしてからJoinだ。
Midステートメントが0.15秒、Strng型の一次元配列に格納してからJoinが0.2秒なのに対して&演算子は約:52秒。
>>127 Midステートメントそんなに速い?
どうやったらJoinより速くなるんだろ?
まだまだ俺は修行不足だな。
まぁ俺は手軽なJoinしか使うつもりはないけどな。
126 :
117 :2008/06/14(土) 00:13:09
>>124 納得しました、ごめんなさい
半年ROMるよ
50000回の結合とかどんな場面だよ
まあぶっちゃけマクロごときで2,3秒遅くなっても問題ない
>>122 Mid関数じゃなくてMidステートメント
ただしVB6まで使える技法で.NETでは速くならない。
>>125 バリバリにチューニング工夫してやっと速くなるが、普通にやるとJoinが速い。
連結はJoinが普通だね。
キモ
向上心のないやつは自分の知らないこと書かれると気分が悪くなるよなw
貧民的プログラミングってやつだねえ がんばれよ
>>130 まさか必要な長さの文字列を最初用意するとき、String$関数使って(6+1)*50000-1個の","を用意するんじゃないよな?
それならMidが速いのは俺でもわかる気がするが。
それとも2回ループ回してもMidが速いの?
MidはさておきJoinは貧民的じゃねーな。 ってか昔はMidは常識だったんだが。
MidとかLeftとかきもいよ。 いーかげんベーシックなんて捨ててほしい 上っ面だけお化粧(?)して実態はただのパクリで出来た言語の呪縛 パくるしか脳のないゲイつ君。 化粧かどうかも怪しい。 既にC言語で解決されてきたポインタやステートメントなどの言語仕様を なぜ新たに別のキーワードでリプレイスするのか。 その結果、脳内置換しながらプログラムする不便さだけしか感じない。 switch文をselect caseにしたからって何か良いことあるのか考えてほしい MSはもっと意味のある新しいものを作れよ
>>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日「前」になっている。おちょくられているような気がするのでもうやめた。 あとは自分で考えて!
横レスだが、質問回答は誰が誰でかよくわからないwww おそらく、if文の判別式が正しく動いてないだろうから、自分で調べるのが最善。 定義と判別式がマッチしていないから、要求された動きが出来ていないと読んだよ。
だから稼働日に連番をふればいんだってば
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も言ってるけど該当した場合の処理が面倒や
日付 休日 連番 手入力した日 修正した手入力した日 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
それより、休みの日の連番を空欄にするんじゃなく、直前の連番と同じにする方が 簡単かも
>>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) の計算式を入れてみてください。
1バイトのAでもaでも2バイトのAでもaでも動くようにStrConvとかLCaseとかいろいろ使えばいいじゃん。
回答有難うございます。
>>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に示された関数(?)をググって みてください。私もこの板を含むインターネットでずいぶん教えてもらいました。 がんばってください。
> 大文字・小文字、1バイト・2バイト Option Compare Textを使うと簡単お手軽な気もするが諸刃の剣 モジュール分ければいいだけの話だけど
>>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のソースを貼り付けてちゃんと 総務部 と表示されたので、ソースの 内容に間違いはないはずです。
>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
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
>>151 シートの指定がされて無いけど、実行時のアクティブシートが違うとかは無いの?
163 :
デフォルトの名無しさん :2008/06/16(月) 09:15:05
>160 実行結果はどうだったの? それから行削除の処理には関係ないけどI1セルへの無駄な代入文2カ所あり。
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)でも同様の症状を確認しました。 対策は・・・誰か詳しい人頼みます。
LookIn:=xlValueをLookIn:=xlValuesとしてみなよ。
167 :
164 :2008/06/16(月) 23:35:32
168 :
164 :2008/06/17(火) 21:43:36
バッチリ動きました。 ていうか、LookIn:=xlValueで動くほうがおかしい。 もっと言えば、実行時エラーじゃなくて、コンパイル時エラーが出てもいい。 xlValueってグラフで使うやつらしい
いや、ただの定数だし・・・
>>169 定数を理解してたらこんなこと書かないって
>>168 イミディエイトウィンドウに
?XlValue
って打ち込んでEnterキー押してみ、正体分かるから
>>164 俺はFindメソッドにxlValueを使ってたDQNを知ってる。
グラフが好きだったから使ってたんだろう。
たまたま動作が同じだからって、たとえばSpecialCells(xlCellTypeConstants)の代わりにSpecialCells(xlFilterCopy)なんてやったら
ヴァカって言われるよな。
>>169 彼が言うようにグラフで使うときのために用意された定数なんじゃない?
x;lAxisTypeクラスってそうなのかな?
なんか164もDQNみたいな書き込みになったな。 すまんな
173 :
169 :2008/06/18(水) 06:21:45
>>171 何のために用意されたにしても、ただの定数。
結局、メソッドの引数が不正だったってだけの話なんだから
コンパイル時エラーじゃなくて実行時エラーなのは当然でしょ、って話。
引数には変数や式も使えるんだし。
174 :
デフォルトの名無しさん :2008/06/18(水) 10:38:23
最近VBAを触りはじめたのですが、全く分かりません 指定されたファイルがあれば、そのファイルを現フォルダから別のフォルダへ移動させたい。 指定されたファイルが無い場合はマクロを終了。 ファイルを別のフォルダへ移動はできましたが、指定されたファイルを探すのが上手くできません。 別のサイトへ誘導でもかまいませんので、教えて下さい。 よろしくお願いします。
やだ
>>174 Sub test()
If Dir("c:\tmp.txt") <> "" Then
MsgBox "存在します。"
Else
MsgBox "存在しません。"
End If
End Sub
可能でしたらどなたか教えて頂けませんか・・? 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します というのが、単に別アプリ(別のエクセル)が前面に出たから見えなくなっただけ なのでは?
例えば指定の曜日とかは自動的にフォントを赤にしたりできるけど、 やっぱりマクロでも祝日はムリかな?
180 :
デフォルトの名無しさん :2008/06/19(木) 10:44:34
>179 曜日は7日周期だから計算で機械的にもとめられますが、 祝日は機械的にさだまっていません。有名なところでは春分の日、秋分の日。 さらに祝日は法律で定まったり日付そのものを変更したり(成人の日、体育の 日、海の日など)とあるので、エクセルなどに実装するのは無理です。 なので、祝日をマクロで実現するには祝日(たぶん振り替え休日も含めてと 思うが)をリストにしておいてマクロで該当する日をチェックして、エクセル表 の該当する日付のセルの塗りつぶしを行うという手順になります。 リストを用意できるか、リストの変更をどう行うかがカギです。
うい
>>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がありません。」と出ます。 間違っているところはどこなんでしょうか? 必要があれば追加文若しくは全文出します。
>>184 Thenの後は改行してみたらどうですか
>>185 おま…MSに消されるぞ
というかGotoなんか使うな
187 :
186 :2008/06/21(土) 10:46:07
>>185 ありがとうございます!
その部分はそれで解決したっぽいです
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に戻すという方法をとってるんですが もっとスマートな方法はないものでしょうか?
>>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
↑だけど追記で。アドインっていうリボンの中に作られたメニューを消したい。
そりゃツールバーじゃなくてメニューバーだ そしてそのコードじゃExcelのバージョンがいくつでもマトモに動かんよ
>>189 ただ単純にbefore:=sheet2で解決しない?
ただし、実際に動作確認してないから分からないけど。
>>194 実はそれも同じ結果になってしまいまして
どうしてもHideされたシートは自身の前位置を譲ってくれません
Worksheets.Addで追加する場合は問題ないんですけどね
なんなんだろう?
>>195 じゃあ、コピー処理した後に並べ替え処理したらどうかな?
ありがとう 並べ替えのループ処理に頼らなくても 一旦VisibleとHiddenを切り替えて、その間コピー処理することで一応解決はできてるんですが なんだか不細工だなあと 仕様ということ納得します
>>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 シートを保護するときに、"セルの書式設定"のチェックを入れないとダメなんじゃ。
>>203 2003とかならそうだと思う。状況からみて2003あたりを使ってそうだけど。
勘違いでなければ、2000あたりはそのチェック項目が無いような気がしたので、汎用性を持たせるなら一回シートの保護自体を解除して処理した方がいいと思う。
そして、処理終了後に再度、シート保護処理を実行する。
>>201 処理と説明が合ってないよ。
塗りつぶしなしにするって書いてるけど、処理自体は赤くするになってるよ。
206 :
デフォルトの名無しさん :2008/06/26(木) 16:15:33
>>203 うまくいきました。
ありがとうございます。
>>204 やはり、その方法の方がいいでしょうか。
ありがとうございます。
>>205 すみません。
二つの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:アプリケーションの定義またはオブジェクト定義のエラーです。 と表示されます。
俺の人生はエラーですがどうすれば直りますか
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 メソッドは、ワークシート上の関数から 駆動させた場合は機能しないようなのです。 どうして、このような挙動になってしまうのでしょうか。 またこの他に、ワークシート上からではうまく機能しないメソッドを ご存知の方はいらっしゃいますか。
>>208 一度、小学生にダウングレードして再起動
ハァハァしかけたけど、野郎なのか。だったら市ね
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) このようにオープンすると本当に立ち上がって見た目がよくないです。 裏でオープンして出力できる方法はないでしょうか? どうぞよろしくお願いします。
>>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 はい、ありがとうございます!
これを使ってなんとか工夫してみます!
>>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 素早い回答ありがとうございます。
早速使わせていただきます。
俺が婦女子だったら、VBAプログラマなんて、この世に生まれて来た 価値が何ら見いだせないような悲しい人生しないで、男に頼んで バンバン子供産んで婦女子ならではの人生を謳歌するけどな。
224 :
デフォルトの名無しさん :2008/06/27(金) 01:45:30
>>221 早速参考にして、
作ることができました。
ありがとうございました。
質問があります VBAで一週間後の日付を出すやり方がありましたら 教えてださい。お願いします
Sub test() Range("A1").Formula = "=TODAY()+7" End Sub
ツールからマクロの記憶を使いグラフを3つ作成して、VBAで設定し表示する事が出来たんですが、全て同じ箇所、重なって表示してしまうんです。 個別に位置を指定して表示する方法ありますか?
228 :
デフォルトの名無しさん :2008/06/27(金) 14:19:01
セルに設定されている、「入力規則」を取得する方法を知りたし。
>>227 '1つ目のグラフの位置設定(???は位置を示す数値)
ActiveSheet.ChartObjects(1).Top = ???
ActiveSheet.ChartObjects(1).Left = ???
'ChartObjects(2)、ChartObjects(3)に対しても、個別に位置を設定する。
>>228 vba validation moug で検索
>>219 > "プログラマ"として食って行けるでしょうか?
> VBAオンリーのプログラマでデスマ(すなわち残業)を避けて生きていくことは
> 可能でしょうか?
無理、世の中そんなに甘くない
事務職で"ちょこっと重宝"されるくらいで"優遇"すらされない
VBAは君ごときでも使えることからも解るように、使える奴は婦女子の中にも腐るほど居る
他言語一切ダメで、基礎から学んだわけではなく行き当たりばったりで覚えたような奴なら尚更
まぁ、OfficeはOfficeでもVSTOを完璧に使いこなせたら、それだけで食っていけるけどな
それこそ残業云々どころか出社すらせず在宅労働で食っていける
とはいえ、身に付けるだけで食っていけるような技術は、君ごときが容易に手に出来るものじゃないけどな
233 :
デフォルトの名無しさん :2008/06/27(金) 20:16:03
Userformから呼び出したSubプロシージャ内で 処理を終わらせるにはどうしたらいいですか? 今は戻り値で判定するのに functionで呼び出しています。 イベントプロシージャに戻らない方法を 教えてください。
> 今は戻り値で判定するのに > functionで呼び出しています。 その方法で良いわけだが > イベントプロシージャに戻らない方法を > 教えてください。 無いけど なんでそんなことをしたがるのかねぇ 初心者の考えることはわからん
Endじゃないの?
233の説明通りならEndは違う
XPとWin2000でexcel2000を利用しています。 ユーザーフォームのcommandbuttonではあまりに味気ないので マウスクリックやエンターキーの両方でフォーカスを取得して操作できる 画像で出来たボタンを作りたいと考えています (マウスオーバーで色が変わり、クリック時にボタンを押したような画像に差し換わる) 使えるイベントの都合的にframeに背景画像を指定するなどいろいろ考えたのですが どうもうまくいきません(画像が切り替わらない・エンターキーを押しても他のコントロールに抜けられない等) 何かよい知恵もしくはもっと適切なコントロールオブジェクトはないでしょうか?
>>224 ならよかったよ。
処理が最大値検索になってるのは意地悪したわけじゃないよ…。
最小値を勘違いして最大値で作っちゃった。ごめん。
>>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はプログラムじゃないだろ
6段の階段なら 1−6段飛ばしの6通りってことか
>>242 うん、VBAはプログラムそのものではなくプログラム"言語"だね
更に言えばプログラム言語の中のマクロ言語に該当するものだな
245 :
デフォルトの名無しさん :2008/06/29(日) 08:06:57
>>241 一段飛ばしする回数をnとすると
(n+H-n*2)!/(n!*(H-n*2)!)
通りになる
nを0からH\2までループして結果を足す
>>233 呼び出された処理の最後で
Application.Quitすればいいと思う。
初心者のうちはけっこうこの命令を
知らないからね。入門書にも出てこないし。
いいわけないだろ ApplicationをQuitしてどうするよw
>>248 IF文などの中で強制的に処理を打ち切るには
Application.Quitしかないと思う。
ExitSubだと呼び出し元に戻ってしまうからね。
250 :
デフォルトの名無しさん :2008/06/30(月) 02:02:31
マクロを編集する時に、例えば赤のフォントにしろと言われても色番号が分からないの ですが、どうしたらいいでしょうか? どなたか教えてください。
>>250 例えば、A1を赤に塗ってみてイミディエイトウィンドに
?range("A1").interior.color
又は、
?range("A1").interior.colorindex
などと打ち込んでEnterキーを押してみる
誰から赤のフォントにしろって言われるの?
>>250 マクロ記録使って実際にその色でセルに色をつければいいだけ。
そしたら番号なんかすぐに分かる。
>>249 だからってApplicationをQuitしちゃだめだろ
処理を終わらせたいのであってApplicationを終わらせたいわけじゃないんだからw
だからEndでいいんじゃないの?
┐(゚〜゚)┌
だからExit Subの代わりにEndを使えばそこで処理は終わるだろ。 変数は初期化されるがな。
>>258 EndってEnd Subのことでしょ?
それだと処理は終わるけど呼び出し元に制御が戻ってしまう。
>>233 は呼び出し元に戻らずに終わりたいって言ってるんだからさ。
そのためにはApplication.Quitしかないって。
>>259 そのEndじゃないよ
でもEndもApplication.QuitもNGだけどな
>>259 違うって。End知らないの?
Exit Subの代わりにEndを書いてみなよ。
そこで処理が終わるから。
ただPublic変数も含めて初期化されるけどね。
セルにでも値を置いておけばいいんじゃないの?
戻ってもいいようなプログラムにすればいいのに
戻った後で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
268 :
デフォルトの名無しさん :2008/07/01(火) 07:13:09
宿題(しゅくだい)は自分(じぶん)でやりましょう。
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人分の偏差値はどうだせばいいのでしょうか? いろいろ失礼なことを言って申し訳ございませんでした。 明日までの課題ですから焦っていました・・・
>>264 「入力規則のリスト」はドロップダウンリストという分類の物で
ドロップダウンリストには入力規則のリスト、フォームツールのコンボボックス、
オブジェクトのコンボボックスなどいろいろあるが
手軽な代わりにあまり弄れないのが入力規則のリスト、
多少面倒はあるがいろいろ弄れるのがオブジェクトのコンボボックス
入力規則のリストでは君の望むことは基本的に出来ないから
オブジェクトのコンボボックスを使いましょう
DropButtonClick イベントで ListIndex プロパティを (ListCount \ 2) にしてやれば
全項目中の真ん中が、表示されるリストのトップにくるようになる
>>271 > 偏差値は定義してますが、計算式がわからないので入力していません。
> 50人分の偏差値はどうだせばいいのでしょうか?
「計算式」というのは数学の問題であって、Excelの問題でもVBAの問題でもない
つーか、ワークシート関数として用意されてるわけだが…
それにしても酷いコードだな
最近では小学校でも算数ではなく数学なんだっけ?
273 :
デフォルトの名無しさん :2008/07/01(火) 10:19:42
>>272 酷いコードですか…ならどういう風なコードにすればいいか教えていただけないでしょうか?
まず自分はコードがわからないんですけどね…
>>271 WorkSheet関数を使うのなら、averageとstdevを使えばOK.
>>273 例えば数量に文字列をセットするなんて、論外だ。
>>274 なるほど。
つまり、出席番号の1〜50も数式?を使ってやった方がいいんですね。
そのやり方も考えてみます。
関数も今は学校なので家に帰ったら試してみます。
小学校からやり直した方がいいよ
>>250 >>251 >>253 でOKだと思いますが、私からも補足。
Range("a1").Font.Color = vbRed
という書き方もできます。
vbRedは、カラー定数(ColorConstants)と呼ばれるもの。
他にvbBlack、vbBlueなど基本的な8色がカラー定数として
定義されているので、赤青黄ぐらいの区別なら、
これを使ってコーディングするのが楽だと思います。
8色の内容については、
VBAEditorから[表示]→[オブジェクトブラウザ]で
オブジェクトブラウザを開き、"ColorConstants"で
検索してみてください。
カラー定数はVBではいいがVBAでは罠がある 人には奨めない方がよろし
>>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で移動するだけで画面からすぐ、隠れてしまう状態です。 よろしく、お願いします。
>>285 >画面の中ほどにコマンドボタンがいつもあるようにする。
コマンドボタンがD列にあるとして
range("D6").select
activewindow.freezepanes = true
>>286 レス、サンクス。
ただ、それは、「ウィンドウ枠の固定」のことですよね。
説明が拙かったですが、求めているのは、例えば、アクティブセルが右に5列移動したら、
コマンドボタンも同様に5列移動するという内容のものです。
>>287 SelectionChangeイベントでActiveCellからOffset指定でコマンドボタンの移動位置を決めれば良い
でもツールバーをフロートで使った方がスマートだな
289 :
y :2008/07/04(金) 21:14:06
>>287 >>288 さんの言うようなやり方もありますが、
CommandButtonを貼り付けたUserFormを表示させておく方法もあります。
(この場合UserFormのShowModalプロパティはfalseにしておくこと)
どちらがいいかは場合によりけりだと思います。
ユーザー定義のツールバーを使うやり方は、Excel自体の環境を
変えてしまうので、他人に配布したりする場合には検討の余地が
あります。でも個人で使う分には、コンパクトだし、
好きな場所にドッキングできるので、とてもスマートです。
2007でツールバーなくなっちゃったしねー
291 :
デフォルトの名無しさん :2008/07/05(土) 15:12:18
しねとはどういう事だ
292 :
y :2008/07/06(日) 00:04:10
>>290 職場の機種更新で、私も2007を使い始めたばかりですが、
ツールバーが使えなくなっちゃったんですか...
日本語の音声読み上げもオミットされたみたいで
ちょっぴり残念。
脱線ごめんね
VBAからCommandBarオブジェクト等は使えるんだけど、 実際に表示されるのはツールバーじゃなくてリボンのアドインタブなんだー タブを切り替えて使わなきゃいけないから面倒なんだよねー
それを手でクイックアクセスツールバーへ追加ってできなかったっけ?
うん、個人使用で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関数で曜日返してくれなかったっけ???
曜日によって処理を変えるとかではなく 曜日を表示させるなら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の値が規定範囲内かどうか調べて、範囲外ならエラー 処理をする"コードを、イベントプロシージャ内に記述するだけです。
数値データから多項式係数を割り出すのにLINEST関数を使ってます。 でもExcelの仕様で、16項までしか対応しないみたいですよね。 VBA使えば255項とか分析できるのかな? ググったけど、そういうニーズは無いみたい…。
そもそも16項もできたっけ? 最近のはできるのかな。 いずれにしても、多項式係数の意味が判っているなら自分で実装できるでしょ。
質問させて下さい。 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が認識できなくなってしまいます。 他に良い方法があるのかもしれませんが、全く思いつきません。 わかりにくい文章で申し訳ありませんが、 どうか、ご教授の程よろしくお願いします。
こちらのスレにて質問させて下さい。 ログファイルから各種括弧(または類するもの)→ () [] 【】 <> 《》 「」 で囲まれた文字列を取り出したいのですが、どのように処理すれば よいのでしょうか?ログなので、取り出すのは任意の文字列です。 例: ***(aaa)** → aaa [warning]*** → warning 月火【水】木金土 → 水
1 FINDで”(”の位置を検索する 2 FINDで”)”の位置を検索する 3 MIDで”(”と”)”の間を抜く 4 かっこの種類だけ繰り返す
シート名には「!」だけじゃなくて「$」や「'」、おまけに「[」や「]」も使える。 しかも、それはブック名にも当てはまる。 その辺は考慮しなくていいのかな?
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
Nameと同一かどうかはわからないけどな
>>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指定しなきゃ駄目だったみたいです。
これがあればいちいち変なループ処理を組み込まずとも、
それぞれの名称を獲得できますね!
いやはや勉強不足でご迷惑をおかけしました…
皆さん、本当にありがとうございました!!
regexp使えば楽だったね。
>>302 >>301 です。
VBAでworksheetfunction.linestってのがあった。
これで実装してみたけど、やっぱり16項までが限界だったみたい。
バージョンは2003です。
以上、報告まで
初歩的な質問なのですが、ブックを超えて操作をさせようとするとどうしても上手く動きません。 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)
でした。でも、自分なりに解決できたとのこと、何よりです。
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だけを置換できるのでしょうか?
>>319 ヒント。
Workbooks.Open ("C:\2.xls")
Workbooks("2.xls").Sheets("sheet1").Range("A1").Value = Workbooks("1.xls").Sheets("sheet2").Range("A1").Value
後は自分で考えれ。
>>321 それだけじゃ emojiip に何が代入されてるのかも分からないよ。
察するに sheets(2) にデータテーブルを持たせてるのかな。
"かきこ" も、何故でしょうか。
ちょっと頭がボーっとしてるんで、私が読みきれてないだけだったらごめんね。
それと、位置を代入してる変数に emoji1 だと訳が分からなくなるから気をつけた方がいいかも。
>>323 ありがとうございます、やはりポイントだけ書き込んでも分かりづらいですよね;
そしてすみません、"かきこ"ではなく"かきお"でした;
sheets(2)はおっしゃる通りで絵文字変換表があります。
A列絵文字を入力して B列絵文字に変換しようと考えたコードなのですが
A>Bはうまくいったものの、戻すのも作ろうとコード丸写しから改編しB>Aのものを動作させると
代入したい部分だけでなくセルの前半ごと変換されてしまいました。
自分用の小さなものなので、変数名は手抜きしています;
うーん。先ずはもっと小さく組んで、それが上手く行ったら大きくして行かないとデバッグ出来ないかもなぁ。 具体的に言うと、変数には予め代入してしまう。 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 変換は置換対象の頭に"*"が含まれていて、ワイルドカード扱いになっていたみたいです。
なので前半がそっくり削れていたんですね;;
こういう場合は*以前を別変数に収めておいて、変換後くっつけると言うようにするしかないのでしょうか?
もう面倒だからRegExpでreplaceしちゃいなYO!!
うそです
329 :
314 :2008/07/08(火) 19:17:00
>>315 ああ、うん、ブック名込みで囲まれるみたいだからシート名だけ見ると後ろだけだね
まあもうどうでもいいね
330 :
67 :2008/07/08(火) 21:43:58
inStrとmidで出来るからやってるんだろうけど、 個人的には正規表現使った方がスマートだと思うんですわ。 あまり正規表現が好まれない理由って何なんでしょうか。
つーか、好みどうこう言えるのは、自分で解決できる奴の特権 人に聞くなら実用上不都合が無ければ良しとするべき
303です。
>>320 わざわざ修正後のコードをあげて下さりありがとうございました!
おかげさまでファイル取得が楽になりました。
>>329 すみません…読解力が足りませんでした…
当初の処理だと既に開いているファイル名称を対象に
ブック判断用文字列"]"
⇒"]"が見つかればシート判断用文字列"'"を直後から探す
⇒"'"が見つかれば直後からアドレス
という風に左側から一文字ずつIFを階層にさせていたため、
最初に"'"があったとしても"]"が見つからない限りブック名称とする処理をしてました。
ファイル名で"]"は入力できなかったはずなので
ブック名称は間違えようがないと思って作ってました。
…今考えると凄まじくめんどくさい処理ですね。
そんな感じなので"]"の前にある"'"は処理上認識しないからと頭の中で完結させてました。
ともあれ、アドバイスありがとうございました!
もっと勉強しておきます…
333 :
y :2008/07/08(火) 23:17:27
>>330 私の場合ですが、正規表現は何となく苦手なんです。
2〜3回のテストではうまくいくようでも、実際に
いろいろな文字列を処理させてみると、どうやら論理的に
穴があるらしく、意図した結果が得られないことが
よくあります。
表現が回りくどくなっても、文字数や位置をもとに単純な
条件分岐を積み重ねる作りにしておくと、事前チェックや
デバッグの際に、各行をトレースして細かいレベルの動作を
明示的にチェックでき、個人的にはとても安心です。
向き不向きもあるようで、人によっては正規表現でひょひょいと
書いてしまう方もいます。「この式で大丈夫」と確信できるのは、
正規表現の動作を頭の中でシミュレートできるからなのでしょう。
とても羨ましいです。
配列操作の練習を兼ね、CreateObjectで一時的に作成したシートに コンボボックスのデータを転記し、ソートした後に配列に書き戻す… といった事を考えたのですが、 Set myWorkbook = CreateObject("Excel.Sheet") とした途端、元ブックのウィンドウサイズが変わってしまいます。 Application.ScreenUpdating = False では防げないようなのですが、 どうすれば挙動が見えないようにできるでしょうか?
ボタンを押すと、変数にA3にある変数を1足したいのですが、 Cells(1, 3).Value = "Cells(1, 3).Value" + "1" とやっても、増えてくれません。 特に変数は使っていませんが、どのようにすれば、変数の値を増やすことができるのでしょうか?
>> 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 たしかに変数なんて使っていませんね、すいません。
なぜCells(1, 1).Valueを"で囲む?
>>338 >340の言うとおり。
Ifのすぐ後ろのCellsを""で囲んでいるのをとる。
>>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
コメントは適当に消してね
344 :
304 :2008/07/09(水) 13:10:31
できました!ありがとうございます!
ぬお。エクセルで正則表現使えたのか! 恥ずかしながら知らなかった・・・。 横からマジ感謝。
346 :
338 :2008/07/09(水) 18:09:41
>>340 >>341 くはー、できました!
ダブルクォートで囲むと意味が変わるのですね。
連番で上がりました。
あとは、シート名に連番をつけていくのが目標です。
VBA楽しいですね、
手作業で面倒だった、EXCELが自分専用の便利ツールになりますね。
ExcelがEXILEにみえてきた
しばしディスプレイから目を離し、遠くの緑をみつめよう〜。
Excel2007 WindowsXPsp2 「ズームボタンが押された状態で」印刷プレビューを開くにはどうしたらいいですか?
Excel-VBA は楽しいだろうが、Excelそのものはあんまし 楽しいものじゃないと思う
ワードとかパワポなんて仕事でも使ったことねえ
「Excelで文章書く奴は初心者」 ってのはよく言われる事だが実際には 全然そんなこと無いと思う。 寧ろWordで作る意味が分からない。
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
>>352 だよな
会社で扱うファイルのうちワードなんて1割もない
取り扱い説明みたいなものを書くのには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にも、行間隔スライダーみたいなツールが実装されたら
すごい便利なのに、といつも思います。
> 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の仕様(不具合)と見たほうがいいのかな?
バグだの仕様だの、ってのは簡単に言ってはいかんのだ。 それを言った時点で全てが終わりってくらい重く考えないといかんよ。 プログラムは言われた通りの事”しか”やらないんだからね。
363 :
y :2008/07/11(金) 06:21:02
>>361 あ、すみません。
>>357 の私のレスに間違いがありました。
DataOption1についてはxlSortTextAsNumbersでOKでした。
訂正します。
でも、それでもうまくいかないのですか。
(うちではうまくいくのですが...)
俺はDataOption1とかの使い方は知らないが、そこを無視すると "2008年6月2日" "2008年6月27日" この文字列の大小は9文字目の"日"と"7で"比較されるから、上の方が大きくなるのは当然じゃないのか? バグでも何でもないと思うんだが。 文字列を日付として大小比較するなら "2008年06月02日" "2008年06月27日" という形の文字列にしないとまずいんじゃないのか? "2008年12月6日" "2008年6月30日" これだと下の方が大きくなるからね。 文字列の大小比較するより、データ、区切り位置、日付でシリアル値に変換した方がいいと思うがね。
ちょっと訂正 この文字列の大小は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
おれ、こういうの気持ち悪いので いったんテンポラリバリアントで取得してタイプネーム確認する 特に日付
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 です。
>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" は、動くね。
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
ああ、確かに書けば動くね。
質問です。1〜4の順にプログラムを進めたいと思っています。 1.メッセージボックス「セルを選んでください」。 2.メッセージボックスのOKボタンを押す。 3.シートに戻り、任意セルをクリックする。(セルが選ばれるまで先の処理に進まない) 4.選ばれたセルの情報を取得。 環境はExcel2000 WinXPです。 このような処理をしたいのですが、 どういう考え方で進めたらよいでしょうか? よろしくお願いします。
Sub test() MsgBox "セルを選んでください" End Sub
>>384 結構厄介だと思うので、もっと楽にできるU/Iで作ってみてから挑戦するといいと思う。
当然ではあるが、>385では2番までしか実装されていない。
387 :
384 :2008/07/14(月) 18:09:53
>>385 書き方が悪くてすいません。でもちょっとワロタ
メッセージボックスを出した時だけ、直後で選ぶセルの情報を取得したいんです。
>>386 厄介ですか。
Worksheet.SelectionChange やAPIでなんとか出来ないかなあと思っていたんですけど・・
>Worksheet.SelectionChange やAPIでなんとか出来ないかなあと思っていたんですけど・・ それが判っていて、厄介じゃないと思うなら自分でやってみてくれ。 説明するのも厄介だぞ。
InputBoxメソッドで Typeを8でどうさ?
390 :
384 :2008/07/14(月) 19:06:52
>>388 いえいえ。どうもありがとうございます。
知っているから厄介だと分かるのだと思います。
別の考え方や参考になる意見を聞けたらいいなあと思ってました。
説明も厄介であれば仕方ないです。
>>389 なんだかよさそうですね。
タイプ8にこんな機能があったとは・・
とりあえずそれでやってみます。
>>386 さんの言うとおりU/I使ってあんまり欲張らないで
ちょっとずつやっていくほうがいいみたいですね。
みなさんホントどうもです。聞いてよかったです。
>385もあながち悪くないと思った暑い夕暮れ
392 :
y :2008/07/14(月) 22:03:21
>>384 SelectionChangeイベントを使う場合の考え方:
パブリック変数を用意し、イベント許可フラグとして用いる。
イベント発生時、イベントプロシージャの冒頭で
イベント許可フラグが立っているか否かを判定し、
プロシージャの内容を実行するか、何もせずにプロシージャを抜けるか
分岐させるようにしておく。
こうしておけば、普段はSelectionChangeイベントが発生しても
何もせずに終わるが、「セルを選んでください」表示後にフラグを
立てれば、次のSelectionChangeイベントでプロシージャの内容が
実行される。
ここでセルの情報を取得し、最後にフラグを元に戻しておく。
---------
ここまで書いておいて何ですが、
明らかに
>>389 のやり方のほうが優れています。
1.メッセージボックス「セルを選びましたか?」 2.メッセージボックス「本当にいいんですか?」 3.メッセージボックス「いいんですね?」 1のところでなれたら使うボタンを追加しとくとか
質問があります。 複数のワークシートにまたがった複数範囲の標準偏差を計算するため、最初は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です。 よろしくお願いします。
>>394 作業シート作って(予め非表示で用意しておいても良いし、処理前に作成して処理後に削除しても良い)
そこに必要な値を書きだして計算する
またはワークシート関数を使わずに、普通に計算してもいいかもな
標準偏差関数のサンプルなんて腐るほどあるから、わざわざVBAから
ワークシート関数(WorksheetFunction)呼ばなくてもどうにでもなる
ここで解説してくれる優しい方々は、やっぱりエクセル1級持ってるのかですな?
そんなもの持ってるやついるの?
398 :
384 :2008/07/15(火) 13:02:18
>>392 レスどうもです。
「セルを選んでください」の表示前にあったセル位置の情報しか取得出来なくて、
>3.シートに戻り、任意セルをクリックする。(セルが選ばれるまで先の処理に進まない)
この3番のユーザーの入力待ちがどうしても出来ません。
>>393 どうもです。
連続した作業になるので、メッセージボックスは1度だけにしたいんです。
VBAのソースコードをカラーで印刷する方法が判りません 印刷品質くらいしか選べなくてモノクロになっちゃいます 誰か教えてください・・・・
print screenで画像保存してそれをカラー印刷すれば良いじゃん
401 :
デフォルトの名無しさん :2008/07/15(火) 17:39:35
VBA初心者の者ですが、 (A:B)列のセルがゼロか空白ならば、 (1:50)の行が削除される構文をどなたか教えて頂けますか。 If Then Else ステートメントを使ってやるのでしょうか。 お願い致します。
>>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
これで一応できるよ
なんか間違えた 無かったことにして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
>>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
>>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
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
>>410 なんか質問がおかしいように思うよ。
>>412 さんの構文の通り、セルに名前を付けてあるの?
名前を付けたセルの値が・・・って事なら構わないんだけど、
何か勘違いしてるかな。
A:B列の、どのセルを対象にしたいの?範囲は無し?
A列かB列の任意のセルに0か空欄があった場合、1行目から50行目までを削除するの?
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プロパティで操作できます。
それをキーワードに検索してみてください。
>>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)とかを使ってデータの最終行を取得するとかをした方が
いいんじゃない?
もう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に指定してるから
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でやろうとしたことと考え方は同じです)
確かに、慣れてない奴にウェブで調べさせた怪しげな標準偏差関数を自作させるよりは、 >420の方が余程まともだな。
422 :
410 :2008/07/16(水) 13:36:35
>412,415,417,418 丁寧にありがとうございます。 すみません説明不足でした。 A列かB列の任意のセルに0か空欄があった場合、 【0か空欄がある行だけ抜き出して削除する】処理がしたいのです。 412,415,417,418を試しにやってみましたが、 1〜50行全て消えてしまったので、これだとちょっとマズいんです。(笑) 誠にお手数かけますが、ご教授頂けますでしょうか お願い致します。
>>422 少しは自分で考えよう
>>1 ★5
>>その他
踊らされてなんでもホイホイ答えずに
多少は質問者にも頭使わせよう
Findのヘルプを読んでみ
>>422 えーーーー
>VBA初心者の者ですが、
>(A:B)列のセルがゼロか空白ならば、
>(1:50)の行が削除される構文をどなたか教えて頂けますか。
どう読み取っても50行目まで全部削除したい主旨じゃん・・
ちゃんと質問してくれよ
まあ答え解らないけどwwwwwww
VBAの前に日本語だな
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 あえて解説はしない。
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 で・・・。何やっとんだワシ・・・。
430 :
410 :2008/07/16(水) 16:22:47
うわ・・・皆様本当にご迷惑おかけして 申し訳ないです。 >427・428 ありがとうございます。 でも、やってみましたが、削除できてないっす。 難しいですね・・・
>>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したらその行消してるだけなんだけど。
教えてください。エクセル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"を入れなければならないのでは?
じゃあ入れて試してみろやボケ
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
Sub test() Range(401).Delete End Sub
>>401 今いちど、何をしたいのかを日本語で誰にでもわかるように書いてみれ。
>>428 "0"だと文字列。数値の0の判定を追加しないといかん。
Cells(a,b)が、とあるRange(Unionであっちこっちくっつけてる)の中に含まれているかどうかを返す関数ってあります?
>>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
446 :
442 :2008/07/16(水) 21:13:48
>>443 ,444
ありがとうございます、無事にできました。
うぜーよ
何がだ
449 :
394 :2008/07/17(木) 02:38:11
レス頂きありがとうございます。
>>395 StDev無しで普通に計算する方法も考えましたが、もっと効率的な方法はないものかと思い質問させて頂きました。
>>420 配列が使えるというのは初めて知りました。
その方法で試してみたいと思います。
>>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列のセルを空白のままにするには でお願い致します。
もう1つ列を作って呼び出さないようにする。
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
検索についてお聞きしたいのですが、 シート全体を対象に検索する場合はCellsで可能なんですが、 特定のセル範囲を検索する場合ってどうやればよいでしょうか? 例えばA1:C10の範囲内のセルだけ"パソコン"という文字列を検索するにはどうすればよいでしょうか。
cellsは全セル対象でおk。 指定範囲は、 Range("A1:C10").Find(What:="パソコン").Activate こんな感じ。 マッチした後の処理が書いてないから、マッチしたセルをactive。
>>456 なるほど。
What;= が必用だったのか・・
ありがとう。
>>457 セミコロン(;)じゃなくて、コロン(:)だよ
あと、「What:=」見たいに使うのを名前付き引数といって
指定()内に記述する順番がばらばらでも大丈夫な引数指定の事
省略した場合はFindの場合(What:=, LookIn:=, LookAt:= …)の順に引数を指定したとみなされる
かなりなスレ違いお許し下さい 過去の株価をVBAで検証したいのですがスキル不足です。 検証の内容は、ごく単純なもので恐らく数十分ほどで組めるのではないかと思われます。 (検証条件=システムは、恥ずかしい位、幼稚なものです。期待なさらないで下さい。 特別な秘密など有したものではありません・・) どなたか有償でVBAを組んで頂けませんでしょうか。 報酬は、先払い3000円・完成後3000円の合計6000円を考えています。 指定口座に迅速にお振込み致します。 二か月分の株価を載せたエクセルデータと 検証条件を説明したテキストファイルを作りました。 これをメールでお送りします。 請け負って頂けるか否か、報酬は上記金額で良いか とりあえずお見積もりして頂ける方メール下さい。 どうぞ宜しくお願い致します。
461 :
459 :2008/07/18(金) 01:10:20
>>460 書留ででもお送りしますよ^^
そうゆうのもお嫌でしたら無償でもいいですがw
よかったらメール下さい
商品コード 数量 商品名 単価 合計 このような列の集まりで、 商品行が増えていくシートで、発注表を作っています。 数量は普段空白で、注文するときに数量を入れて、 数量がない行は削除(上にシフト)して、プリントアウトしています。 最終的に「数量が空白」を全部消してからプリントになります。 で、これをマクロにすると 数量(一番初めの商品は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 メール送りました。
とりあえず内容見て考えさせてください。
>>462 このスレの410宛てのレスを読め
大体似たような処理で出来る
>>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
香ばしいこと行われているようですねw
470 :
デフォルトの名無しさん :2008/07/18(金) 16:09:08
worksheetsを追加した際に そのシートにWorksheet_Activate() も追加したいのですが、どのように指定すればできるのでしょうか?
普通にやればいいじゃん
472 :
470 :2008/07/18(金) 17:21:42
今 worksheets.add after:=activesheet で新しいシートを追加するマクロがあるのですが、worksheets.????みたいな感じでなにかできる方法があるのでしょうか? マクロで追加したシートにマクロを記述する関数などありましたら教えていただきたいです。
だから、「VBAを使ってVBAコードを記述する」方法を普通にやればいいだけだってば 検索すればいくらでも情報は出てくる
474 :
470 :2008/07/18(金) 18:28:56
ありがとうございます。 検索したら With ThisWorkbook.VBProject.VBComponents.Item("Sheet2").CodeModule .InsertLines 1, "書きたいコード" End With でできるみたいですね。 ありがとうございます。
本当にやりたい目的と、今とろうとしている手段が乖離している気がするが、まあいいや
>>472 hoge = activesheet.index
worksheets.add after:=activesheet
sheets(hoge+1).activate
じゃダメ?
>>476 アクティベイトしたいんじゃなくて、ハンドラを入れたいんでしょ。
>>470 普通に標準モジュールにコードを書けばいいんじゃねーの?
イベントハンドラが使うならクラスモジュールを使えばいいし
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回目の処理で止まってしまうのが、よくわかりません・・・。
>>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が言ってるだけ
基本的に削除するセルを基準にしちゃだめだろ
>>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なんて使うとコードが汚れるとさえ思える。
へー
487 :
y :2008/07/19(土) 10:27:10
>>484 元の質問とは関係ないですが、コードがインデント付きで表示されて
いるのでびっくりしました。しかも、VBAEditorが全角スペースを自動的に
半角スペースに変換してくれることを初めて知りました。
(
>>484 をそのまま貼り付けるとエラーになると思い込んでた)
これはVBAEditorの仕様でしょうか?
それとも「全角空白は半角に変換する」みたいなオプションが
どこかにあるのですか?
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) ブラウザに因っては正しく表示&コピー出来ない場合もあるけど
因みに↑は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 の別解。★の行も含めて消えますが)
うぜーよ
>>485 他の言語からやってきたものからすると、
While ~ Wendの方がとっつきやすいんだよ。
単なるキーワードの違いだがな。
ただ、While ~ Wendだとループの脱出が…
493 :
485 :2008/07/19(土) 18:43:46
やっぱりそうだよな、他の言語やってるとそうなんだけどね。 でもVBではDo...Loopに限るよ、Do...Loopの仕様は反復制御として完璧だからね。
uze-yo
心の狭い子…
496 :
デフォルトの名無しさん :2008/07/19(土) 23:01:26
こんばんは。VBE初心者のものです。 講義の宿題で7×7の魔方陣をVBEで解いてこいといわれました。 しかしながら自分のスキルでは動にもなりませんでした。 自分はIFやDim等までしか習っていませんがそれで解ける方法があったら 誰か助けてください。
ループで全通り回せばいいだけじゃん
・中央は25 ・1列の合計は(1+25)*25/5で130
ちがったか 1から25の合計は(1+25)*25/2=325 1列の合計はこれを5で割るから65だな
最上段中央に1を配置したら、右上に移動しながら2,3,4と次の数値をと入れていき、7の倍数時は右上ではなく下へ移動 上下、左右がループしてるとして(つまり1行目の上は7行目、7列目の右は1列目)この処理を続ければあっという間に完成 奇数の場合は上記の法則が使えるので超簡単 因みに7*7の場合は(1+7^2)/2*7で175が1列の合計 コードはForと算術演算(数値計算)が使えれば条件分岐(IF)すら要らない簡素なもの 小学生あたりにはオススメの問題だ
>>501 複数の解(回転・鏡像を除く)が存在する場合も無視?
無視って何を?
どうやったら条件分岐使わずに書けるのかわからん その小学生にお勧めのコードをお教えくださいませ
あと、開始座標がどこでも結果同じだろ。 マ板とは思えんなここ
別に501が唯一の解法だなんて書いてないし、 解法の一つとしては間違ってないわけだが、この子は何が気に入らないんだろう? 何か勘違いしてるのかな?
ちょっと書くだけで過剰反応するバカがいるから面白がってるだけ
>>501 にからんでるやつ頭悪そう。
魔方陣には特殊な解があるぞという回答に対して他の解は無視かよだなんてスジ違いのイチャモン。
頭が悪いんだろうな。
ごめん。魔方陣って何? 面白そうなのに全然話に参加できないんだけど。 って人が多いと思う・・・俺含め。(俺だけ?)
魔方陣を知らない人は少ないと思う。 君は少数派。
ググれカス
寧ろwikiれ
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で
シミュレーションせよ、ということなんでしょうね。
魔法も使えないって おまえら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個の配列について、」
試してみた(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 深さの問題じゃないね
講釈ばっかで回答が一つも無い件
Sub 魔方陣() range("A1") = "7×7の魔方陣" End Sub できたよ〜
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
よくわからんが size / 2 + 1
を、 (size + 1) / 2 にするだけなんじゃ?
525 :
522 :2008/07/20(日) 16:11:11
それが原因なら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
所謂ISO丸めだね。小数点以下一桁を丸める場合、その桁が5のときは偶数になるように丸める。 四捨五入とは違うから要注意だ。
>>517 nestingは10じゃなかったっけ。
すみません、よくわからないので教えてください(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に変えても駄目でした
そりゃそうだ そのコードだと"\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使えるとはとても言えないぞ
>VBA使えるとはとても言えないぞ VBA使えなくてもお前ら使えばいいだけだしなw
>>531 regexpを使うと良いよ。正規表現。
パターンは ".*?\n" で行けるかな。
executeでコレクションに格納してから for each in で項目引っこ抜いても良いし、
submatchで引っこ抜いても行けると思うよ。
セル内改行が \n で取得出来るか、ちょっと試してくるね。
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 を "" に置き換えて除去すると良いかもね。
あ、取り出される要素数がその都度違うようだったら、 hogeMatch.countの回数だけ繰り返してね。
ああ・・・ vblf で split するのが一番良かったかもしれませんね・・・。 スレ汚しすいませんでした。 Sub piyo() Dim hoge hoge = Split(Cells(1, 1), vbLf) Debug.Print (hoge(0)) End Sub ごめんなさい。
>>536 改行コードがLF固定だったら、
MultiLine = True, Global = Trueにした上で
"^.*"でやれば無駄な改行コードも取れずにそのまんますんなり行ける。
ああ、multilineでセル内改行取れましたね・・・。勉強になります。
行分割するだけなのに、何故に外部コンポ引っ張り出して正規表現使う必要が・・・・・
そう言う年頃なんだろよ。
頭でっかち
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
みたいな指摘を受けてしばしば鬱になります。
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
予想では、再帰呼び出しがされればされるほど
使用メモリは増え、使用可能メモリは減ると思いましたが、
実際には出力される数値はまったく変化しませんでした。
スタック領域は、これらのプロパティで出力されるメモリ数とは別なのか、
それともこのプロパティは動的な意味でのメモリ容量ではないのか。
メモリは確保済みなんじゃないの?いや、知らないけど
これに書いてる
ttp://k-flow.blog.so-net.ne.jp/2008-03-24 >ちなみに、Application.MemoryFreeプロパティで得られるフリーメモリー容量は、どのような条件下においても、常に1MB程度です。
>また、Application.MemoryTotalプロパティで得られるトータルメモリ容量は、常に上記の2つのメモリ容量の合計となります。
これなら、スタックで使えるメモリ量も常に1MB程度って事じゃないかな?
まあ再帰の数で困ったら まず末尾再帰の形に書き直して(ステートを持ちまわるようにする)、 それからループに書き直すといいね。
>>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固有の質問ではなくなってきたので、他スレで同じ質問をするかもしれません。
>>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とか勉強すればいいんじゃね?
ごめん。最後の関数のresult&はいらん。
選択範囲をset して For Eachでまわそうとすると 余分にまわりませんか? Selection.Countでみるとときどきなんか多い…わらし?
コード晒せよ
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 手元にあるリファレンスブックをざっと見ましたが、
そういう関数は私には見つけられませんでした。
その識別子を何に使いたいのか教えてくれたら、
他の方もアドバイスしやすいと思います。
>>557 だいたいその認識でOK。
誤解の無い様に言っておくが、(勘違いしていたらすまんこ)
全ての再帰がループに直せるわけじゃなくて、末尾再帰だけね。
562 :
デフォルトの名無しさん :2008/07/25(金) 11:11:35
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 をつけてもだめでした。
A123を先にB123に変換 A12を変換 B123をA123に変換 では多分駄目なんだろなぁ
>>563 あくまでおいらのやり方ね。状況に応じて何種類か使い分けてるね。
・
>>565 さんのやり方。
str1の検索ワードにlenでの長さを出して、降順にソート。長い物から置換して行く。
・オートフィルタで完全一致させる物を抽出。んでマッチにしたセルを置換。
・上二つや、組み合わせで対応出来ない時はregexpのreplaceを使う。(regexpの話出ると荒れるんだよね・・・)
たぶん、検索文字列と置換文字列がデータテーブルに存在するならば、
オートフィルタか、長い順に置換で出来るような気がするよ。
>>564 >1つのセル内には複数の文字列群があるため(A12とA123が同一セルにある)
かぁ・・・・。
データテーブルを文字列の長い順にソートしてから、
オートフィルタの部分一致で抽出、見えてるセルにreplaceでどうかな。
568 :
563 :2008/07/26(土) 07:57:01
569 :
563 :2008/07/26(土) 08:07:43
置換の
>>563 です、
あぁ・・・。
以下のような場合がマズイかもしれません。
もう少し調べたり考えたりしてみますね。
例)置換リスト A123→B123
対象データセルの文字列
A12 A123 A1234
※A1234までB1234になってしまう。
一旦配列に取り込んでVBAでReplaceした方がいいんじゃないのかな
あ、Replace関数使うんならLen関数も一緒に使うとかしないとダメだな
置換条件が結構厳しそうだね。 replaceだと一致は理論上の部分一致だし、 1セルに複数の文字列が入ってるとなると、オートフィルタも限界あるなぁ。 regexpのreplaceメソッドが良いような気がするけど、詳しい人の意見も聞きたいな。 セルの中で、どんな風に文字が配置されてるかが分からないけど・・・まぁ行けるかと。 A12A123A1234 のうちA123だけを置換したいなら、 "A123^A"で引っ掛けられるかな。
VBAのreplace使えるのって、A123もA1234も置換する場合に限られるような気がする。 もし、A123は置換するけど、A1234はそのまま、って場合にはちとまずい。
だから配列に取り込むんだよ
575 :
y :2008/07/26(土) 14:27:52
>>569 まず、
>>563 で
>文字列A12をB12に置換したいが、
>文字列A123は置換せずそのままにしたい
と書いていますが、2つの要求同士が矛盾しているので、
そのような動作はありえません。
解決の可能性としては、
>>572 の「セルの中でどんな風に文字が配置されているか」がポイントです。
つまり、文字の配置に規則性があるかどうか、ということです。
たとえば
>>569 で、対象データセルの文字列として「A12 A123 A1234」という例が示されていますが、
これを見る限り「文字列に含まれる各単語は、スペースで区切られている」という規則性が感じられます。
もし、すべての対象データセルの文字列がこの規則に従っているなら、望みの操作は可能です。
まずはすべての文字列に共通する規則性があるかどうかを確認し、
もし上記のような規則が存在するなら、
>>570 と
>>574 が薦めている
「配列にとりこむ」方法を検討してみてください。
この場合、Split関数が使えます。
>>569 の例のように区切り文字がスペースって事なら(半角と全角が混在してるな・・・)
ActiveSheet.Columns("A:A").Select
For Each c In Selection
c.Value = RTrim(Replace(Replace(c.Value," "," ") & " ", str1 & " ", str2 & " "))
Next
とかでどうかな、遅いし全角スペースは半角になっちゃうけどね
何でもかんでもVBAの機能だけでやろうとすんなって。 使える物は何でも使おうぜ。 VBSだろうがAPIだろうがWHSだろうが、VBAから使える以上、VBAで良いと思うぞ。
Microsoft VBScript Regular Expressions 参照して、正規表現で置換かけるのはダメなん?
完全一致を望むならば、やはり正規表現だと思う。
580 :
y :2008/07/26(土) 23:48:07
>>576 のレスを見て、全角と半角の混在に気づきました。
これではJoinは使えませんね...
私は正規表現は苦手で、普段はあまり使っていないのですが、
たしかにこの状況では正規表現が良さそうな気がしてきました。
半角・全角スペースどちらにもマッチしてくれる\bがかなり便利。
"\b(A12)\b" を探して "B12" にReplaceするだけで済みますね。
どんな物を置換したいのか、どんな並びになってるのかが分かればマッチパターンを考える事は出来まっせ。 もし、住所録の置換なんかで、 ○○県アルプス市〜〜 → ●●県foo市〜〜 ××県南アルプス市〜〜 → △△県bar市〜〜 みたいなのだと、正規表現じゃないと無理ですな。 何にせよ、規則性を見つけ出してパターンを組む事から始めよう。
XP Excel2003で質問なのですが 480×640の画像のRGBの値を画素ごとに R(480,640),G(480,640),B(480,640) という配列に読み込みたいのですが可能でしょうか?
スレ違い
画素ごとに・・・ってあんた。
1000万画素の写真として、3000万個の配列ですか・・・。 考えただけで鬱・・・。
>>586 もし暗算が苦手でしたら、WindowsにしろLinux(Gnome)にしろ電卓アプリが付属していますので是非お使いください。
え・・・普通480×640って言ったら画像サイズの事じゃないの? 画素数は密度によって違うと思うんだけど。
>>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サイトを参考にチャレンジしてみてください。
エクセルっていろんな事出来るんだね・・・ほんとすごいです。
592 :
y :2008/07/27(日) 16:24:18
すみません。
>>590 は「VBA解説書」→「VB解説書」の間違いです。
さすがにExcelVBAの解説書で、画像ファイル処理の例は見たことはありません。
ある意味
>>584 ですが、ついつい答えてしまいました。
593 :
583 :2008/07/27(日) 16:57:26
画像サイズと画素数を混用してしまったせいで変な誤解をさせてしまったみたいです
すみませんでした。
>>590 非常にわかりやく解説していただいてありがとうございます!
ずばりこれを知りたかったんです。
ありがとうございます。
結局、置換の質問した人はうまく出来たのかな。
今頃痴漢してつかまってるよ
( ´_ゝ`)
597 :
563 :2008/07/28(月) 22:36:20
ご報告が遅くなりましてすいません。置換の人です。 みなさんの知恵をお借りして、 私のつたないプログラム能力でなんとか作ってみました。 結局、セルを1つずつ読み込んで、 セル内の文字列に対してregexp正規表現 \b(str)\b で置換 という形にしたところ、要求を満たすことができました。 みなさんありがとうございました!
おめでとう
入力された文字が漢字か平仮名かを判定することは可能でしょうか?
はい。
どうしればいいのでしょうか 教えてください
全てのひらがなのリストを用意し、入力された文字がその中に見つかるかどうか判定すれば宜しいのではないかと。
そんな無駄で面倒なことしなくても、文字コード判定すれば一目瞭然かと
>文字コード判定 こいつを具体的に。
VBAからSASを操る事は可能でしょうか。 もし可能だったら、どんな感じで行えるのかを教えてくださいませ。
> VBAからSASを操る事は可能でしょうか。
可能です
> もし可能だったら、どんな感じで行えるのかを教えてくださいませ。
>>1 ★3
ありがとうございました。
>>604 平仮名の文字コード知るには
Cells(1, 1).Value = Asc("あ") ' -32096 を返す
609 :
デフォルトの名無しさん :2008/07/29(火) 22:44:03
グラフを描くとき、データ範囲設定において、 A1〜A12のデータがあり、A1〜A6、空白データ、A7〜A12と設定してグラフを描きたいのですが、 空白データの設定がわかりません。 空白データA1000〜A1010を設定して、Unionで範囲結合しても駄目でした。 できる限りシートのデータ位置は移動させたくありません。 何かよい方法がありましたら教えてください。
>>608 で、それが>602よりも無駄でもなく面倒でもないと?
>>609 見せないダミーのセルに空白データを抜いてコピーするんじゃダメ?
>>602 もしアルファベットやらカタカナやらが入力されても漢字と判定するって事か
どういう入力があるのか知らんけど
>>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
>>615 わざわざイミディエイトウィンドウで実行しなくてもいいんじゃないの?
つまり、End Subの前の3行(コメントも入れて4行)を
Shell strComponentPath & "bld.bat"
に置き換える。
617 :
デフォルトの名無しさん :2008/07/31(木) 21:46:16
ブックを変更して、ファイルを閉じようとしたり、エクセルを終了 させようとすると、 「変更を保存しますか?」 とメッセージが出力されます。 ここで、「はい」、「いいえ」、「キャンセル」のどれが 選択されたかを取得する方法ってありますか?
あります
ちょっと前からこのスレ見てるけど、やけに意地悪なやつがいるな たぶん同一人物だろう
いいえ
わざわざ質問に答えてて充分親切だと思うよ。 方法の詳細を知りたいなら、ちゃんと質問しない方が悪い。
名簿にオートフィルタを使い、名前の列(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 修正すべき箇所や効率的な方法がありましたら教えてください。
cells(1,1).end(xldown) で、可視セルを1段ずつ下げて行くとか?
626 :
デフォルトの名無しさん :2008/08/01(金) 17:41:24
グラフで折れ線を描くとき、間にデータがないと線でつないでくれません。 ツール、オプション、グラフで線を補完すると線は引かれました。 ここで質問です。 間を補完したい項目、補完したくない項目があります。 ある項目のみ補完する方法があれば教えてください(VBAでも可)
データを線形補間して、別のシートに出力、グラフ生成
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 すごい面白そうですが、私はやったことがありません。
コレクションのすべてに命令を掛けるループは for each が妥当だとは思うんだけど、 for でcountして回すのと、for eachでコレクションにループ掛けるのではどっちがスマートなんだろ。 今、実測出来る場所じゃないんだけど、誰か測定した事ある人いますか?
何も事情がないかぎりFor Each使ったほうが分かりやすい。
値渡しとか参照渡しするくらいなら はじめからPublicで定義しといたほうがいいとおもうのはおれだけ?
Publicはできるだけ少なくするのが基本 なくせるならないほうがいい
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 ステートメントを使うことを
好む方も、たいていそれが理由だとか。
でも速度的には、下の例はループのたびに補正演算が入るので、ほんのちょっと
遅くなってしまうかも。
僕はいつもこうしてます。気分的なもので。 こっちのほうが早いような気がしてます。 lngCnt = myCollection.Count For i = 0 To lngCnt - 1 ary(i) = myCollection.Item(i + 1) Next
VBAで大量のコレクションをループすると非常に遅くなりますよね
速度は気にするべきじゃない。 なんにせよ、パフォーマンスは計らないとわからないという一面もあるし。 最初はアホなコーディングさえしなければおk。
641 :
y :2008/08/02(土) 18:31:11
アホなコーディングといえば、初心者の頃の私は
>>634 をさらにつきつめたような
考えを持っていて、ある日「どの関数でもループにiを使うなら、iをパブリック変数に
しておけばいいじゃない!」とひらめいたのです。そしてその方法で2つぐらい
モジュールを書いて、「これはどんな解説書にも載っていない画期的な方法だ!」と
思い込んでいました。
確かに画期的だね
VBAはブロック単位で変数が初期化されるわけじゃないから、 初期化処理を書かないまま特定の処理部分をループにしたりすると、 前回の内容がそのまま流れてきたりしてしまうんだよなあ。
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 すいません。もう少し詳しく教えて頂けませんか?
>>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)に金額を書き込む」
とやっていると、伝票書式のデザインを変更したいときに柔軟に対応できませんが、
このやり方なら、数式を埋め込むセルを変えるだけで済みます。
また、参照設定さえすれば、さらに別のブックからもこれらの関数を利用できます。
機能不全になる前に気づけよw
他人に迷惑かけない限り別にいいじゃない。 641じゃないけど実際に痛い目にあうとよく覚える。
カスタムシート関数の場合は共有設定でも見られるのがいい
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
ユーザー定義関数か・・・ちょっとやってみよう
C#圧倒的だな
そうね 圧倒的に遅い
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 のように使えたらいいのですが・・・
Range("C3") = Range("A3") でおっけ
659 :
657 :2008/08/03(日) 00:24:34
A3をC3にコピーするだけじゃなく 汎用性を高めるために 選択セルの行の 1列目を3列目にコピーするようにしたいのです。(実際は別ブックへ)
do until cells(1,j).value = "顧客名" j = j + 1 loop cells(i,j).copy とか?
普通に[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
おっと
665 :
デフォルトの名無しさん :2008/08/03(日) 22:53:52
663のを教えて。
富士通もとうとう日本語が喋れないのが標準になったか
667 :
626 :2008/08/04(月) 03:41:16
>>629 >次に、補完したくない要素について、線の色を背景色と同じにし、見えなくします。
一部線が引かれているところがあり、そこは見えてもらわないと困るのです。
>>667 データを線形補間して、別のシートに出力、グラフ生成
669 :
デフォルトの名無しさん :2008/08/04(月) 07:55:36
Excelの機能には限界があるんだから、Excelでできない事は自分でやらないと
>>667 線全部じゃなくて、要らないところだけ背景と同色にすればいいだろ。
671 :
y :2008/08/04(月) 14:08:37
>>667 >>670 でフォローしてくださっている通り、
線全部ではなく、一部分だけを背景と同色にできます。
>>629 のコード例はそのつもりで書いたもので、
系列1の線の、4つ目の線分だけを見えなくします。
つまり、点1から点4までと、点5から最後の点までは
きちんとつながっている状態です。
手作業で(マウスで)試す場合は、ある線をクリックして、
さらにもう一度クリックしてみてください。
クリックされた線分だけがアクティブになるはずです。
その部分だけに、お好みの書式を適用できます。
その動作をマクロ記録すれば、VBAでどう表現するのか
分かりやすいと思います。
>>668 でもいいと思います。
マクロ記録はAlt, T, M, Rと覚えてしまったら楽。
一つの変数を複数のユーザーフォームで使いまわす方法ありますかね?
>>672 やめてくれ。マクロ記録するたびにあのボーカルの顔が浮かんじまうw
>>673 「使いまわす」を詳しく。
675 :
デフォルトの名無しさん :2008/08/04(月) 21:21:01
久しぶりにマクロ組んで保存して使おうと思ったら・・・・ マクロ有効形式でなければ保存受け付けないだの セキュリティレベルの警告も出ないまま無効だの ファイルが安全な場所になきゃ有効にしてくれないだの すげーむかついた vista視ね
676 :
デフォルトの名無しさん :2008/08/04(月) 22:03:41
visuta厨涙目w
それWindows VistaだからじゃなくてOffice 2007だからだろ。
2007のリボンは本当にひどい。 慣れとか言う以前に、慣れても面倒。 クリック回数が増えただけですわ。 Alt+F8 , Alt+F11 で慣れてないとVBE環境もつらい・・。
他に選択肢ないのがつらいね あぁ待てばいいだけか
質問です。現在、ユーザーフォームを.PrintFormを使い印刷しています。 このユーザーフォームは、 上側にボタンが横一列で並んでいて 中央にコメントボックス、 下側にラベル という形になっています。 このユーザーフォームを、コメントボックスとラベルのみを印刷、 又は印刷時にボタンを非表示にする、ということは可能でしょうか? もしできるのであればその方法を教えてください。お願いします。
681 :
デフォルトの名無しさん :2008/08/05(火) 10:23:10
>ボタンを非表示にする、 という事であれば、 userform1.button1.visible = false にすれば 非表示には出来る
682 :
デフォルトの名無しさん :2008/08/05(火) 11:29:34
セルに文字列があり、変数に取り込みメッセージの一部に使いたいのです。 しかしセルに改行が入っていると当然メッセージでも改行されます。 改行を取り除く方法があれば教えてください。
vbcrlfを探して取り除く。
Alt+Enterでのセル内改行はvbLfのみだぞ .Value = "a" & vbCrLf & "b" みたいにすれば、vbCrLf での改行も不可能では無いが 普通はvbCrLfを取り除いても意味無い
excelでデータベースのロジカルチェックを掛ける事を考えておりまして、 つきまして、プログラム構造、モジュール構造についてアドバイスを頂きたく投稿します。 ロジカルチェック自体は、200-300個あります。 今考えているのは、1つのモジュールに、private sub で200個のプログラムを書いておき、 1つの sub で200個のチェックプログラムを call しようと考えています。 そこで質問なのですが、1つのモジュールにたくさん詰める事は好ましくないのでしょうか。 保守を考えると、private sub A010010 のように、チェック番号をプログラム名にしておけば、 Ctrl+Fの検索で、見つけやすいかなぁ。と思っています。 皆様だったらば、どのように構築していくか等、アドバイスを頂ければ幸いです。 よろしくお願いします。
ストアド書いて、befor triggerにしろ
勉強不足で申し訳ありません。ストアドプロシージャは初めて聞きました。 データベースはSASで作成されているのですが、SASを使える人が少ない上、 教育に金が掛かる&SASライセンスが高い。と言う理由で、 なるべくコストの掛からない方向を考えている次第です。 統計解析を行うので、データベースをSASから変える事は難しいです。 イメージとしては、SASで作成されたデータセットを1つのブックに統合し、 その統合ファイル上でロジカルチェックを掛けられればと思っています。 当方、ACCESSやSQLの知識が無い為に、ストアドと言う単語も初めて聞いたのですが、 やはりEXCELのみで完結させるのは難しいでしょうか。 もし可能であれば、もう少し詳しく教えていただけますでしょうか。よろしくお願いします。 情報小出しのようになってしまい申し訳ありません。
>>687 長い目で見れば、弊社のような専門家にお任せいただくのが一番かと存じます。
689 :
デフォルトの名無しさん :2008/08/05(火) 21:30:04
690 :
y :2008/08/05(火) 21:38:27
>>685 最適な構造は、最終的にどういう運用をしたいのか
なるべく具体的にイメージすることで見えてきます。
細部の仕様も、その過程で決まっていきます。
・常に全種類のチェックが必要か
→状況により、「前半のチェックは省略したい」などの要求が起こりえる場合
→Call文のコメントアウトで対応?
→スイッチUI実装?
→チェックする項目のプリセットを保存できれば便利?
・エラーレポートはどうしたい?
→Excelシートに出力
→テキストファイルに出力
・修復ロジックも実装したい?
そのプロジェクトは一人で担当しているのですか?
もし何人かでやっているのであれば、上のような点を
協働者とも相談してみてください。
>>689 ありがとうございます。ただ、SASでステップは走らせません:(
すいません。私の質問の仕方が悪かったようです。
データベース、解析は一切関係無いとして、
1つのEXCELブック内にあるデータ同士の整合性をチェックするプログラムが200個あります。
この200個はどのように書いて行く、もしくは作成していくべきでしょうか。
個々に呼び出す必要はなく、必ず200個全てを走らせます。
1つの標準モジュールに200個羅列して行くべきか、モジュールを分割するべきか、
はたまたストアドを利用するか・・・。
ストアドプロシージャを調べてもEXCELと関連のあるページは見つけられませんでした。
本当に申し訳ありません・・・。
>>690 レスありがとうございます。
組み込んだロジカルチェックは必ず全部実行させます。
エラーレポートに関しては、後々処理が出来るように、別ファイルにダンプし、ログとして集積させます。
そして、レポートを発行する際に、管理番号でオートフィルタを掛け、
マクロでレポートの形にして、発行出来るようにする事を考えています。
プロジェクトとしては、これから提案して変えて行こうと思っている段階です。
その為には、具体的にロジカルチェックをEXCELのみで掛ける事が重要と思いまして、
質問をさせていただきました。
>>692 運用がわからんからなんとも言えんが、パフォーマンスなんかは問題にならんの?
# そして全く無視される>688w
>>693 private sub で200個を1つのモジュールに記載して、
呼び出し用の sub で200個を call する事は問題が無いのか、そこが気になっています。
そこまで多くのプログラムを1つのモジュールに書いた事がありません。
本当に動くのかも悩みの種です。
統合ファイルの内訳としては、その度に変わるので一概には言えないのですが、
平均すると25-30シートで、1つのシートに多くとも2000行程度なので、問題はなさそうです。
>>694 ・Subではなくて、FunctionでBooleanを返したほうが良いのでは?
・一つのモジュールに入る大きさのコードなら、どれだけ書こうと全く問題がない(限界を超えたら
実行時エラーとして教えてくれる)
・保守を考えるなら、第三者が見てわかりやすい関数名にしたほうが良い
・関数名には日本語が使えて、さらに日本語を使っても全く問題がないので、日本語を使った
関数名にするというのも一つの手
>>695 レスありがとうございます。
functionのboolean戻りは良いですね。
booleanで返した時に、エラー項目を引っ張る際にもう1段踏まないと行けないのがつらそうですが、
何とか対処出来そうです。
やはりモジュールに限界はあるのですか・・・。でも実行時エラーが出るなら安心ですね。
実はチェックリストが存在していて、そのチェックリストを基にプログラムを組むので、
チェックNo.のコードを関数名にするのが良いと思いました。
アドバイスありがとうございます。
200ねえ… そんな量じゃなければ、私ならインタフェース使ってクラス量産かな。 (なんせ200もクラスがあるとウザいので) これなら処理を値として扱える。
>>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でいいと思いますが、「どのようなエラーなのか」まで
表現したい場合は、後者の方が都合がいいかもしれません。
COM経由で呼べる組み込み言語ってないだろうか。 適当にJScriptインタプリタ起動できたりしないのだろうか。厳しいかな。
ときどき 0& ってのを見るんだけど、これってどういう意味ですか? If Len(buf) = 0& Then〜 みたいな感じです
Long型の0
ごめん うそ
>>700 Microsoft Script Control
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つずつ範囲から値を配列に格納しようとしていますがうまくいきません。
この考え方でも大丈夫です。中途半端でも構わないので、
とりあえず書いたコードを貼ってみてください。
春日部市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 に変更すると同じ事が出来たのですが、これだと何か不都合が出たりしますか?
変数のスコープについて教えてください。 全ての標準モジュールで使用出来る範囲を付与するには、 どの部分に、どのように宣言したらよろしいのでしょうか。
710 :
y :2008/08/06(水) 20:06:42
>>708 あなたのコードの方が良いように思います。
ReplacementのところはCstr(idx)にするとより丁寧です。
711 :
y :2008/08/06(水) 20:11:16
>>709 付属のヘルプで、
「Public ステートメント」
「Public ステートメントの使用例」
を検索してみてください。
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個で変動します。
最近、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へ
つまり一次元配列から二次元配列へ一気に代入する方法はないでしょうか?
VBって、配列は弱いんでなかったっけ。 配列数指定しないといけないし。
1回の格納ごとにredim preserveしていってもそこまで遅くは無い。 というか、あきらめるべき。 ちなみにredim preserveを減らそうがためにVectorみたいな 一度にアロケートする成長リスト形式にしても速くならなかった。
724 :
デフォルトの名無しさん :2008/08/08(金) 00:46:27
あ、ごめん 上レスぜんぜんみてなかった
>>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程度なら感じるほどに遅くなるよ。
>>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
>>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
時間計るのに、ミリ秒まで計る方法ってある?
API
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 で公開されているモジュールを利用しています。
>>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 で
っていうかこの話、配列クラス自作しちゃった方が早い気がする
無駄に注文多くて我が侭なのに、デフォで用意されてる配列でどうにかしようってのが間違いだろ
ExcelVBAでやる時点で間違っている
738 :
デフォルトの名無しさん :2008/08/08(金) 21:23:40
今のPCなら数百のシートを操作してもそんなにストレス感じないのに msecオーダーで速度求めるならC++で書けよなと思った。
正直言って、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 で大正解です。これからも頑張ってください。
VBAでいろいろ書いて「これおっそいだろうなー」って思っても たいがい人間の認識できる速さのプランク長ぐらいで終わってしまう。驚き
ただあれだ。 ページの表示設定を印刷モードだっけか。あれにしてVBA走らせるとむちゃ処理重いな。 screenupdate falseにすりゃ良いんだけど。 あと覚えてるのだと、cells.autofitがむちゃ重い。 その狂ったマクロ作った奴は、流石にクレーム食らってた。
FSOでネットワーク上のディレクトリ走査するのをExcel関数にして羅列してもなかなか遅くできる。
データの多いシートのAutoFitoはやばいぞ、VBAじゃなくても普通に遅い
質問です。 マクロでPCのシャットダウンはできるのでしょうか? 出来たら、やり方を教えてください あと、MsgBoxをのバックを画像にすることは出来ますか? Windows98 Office2000 マクロ初めてまだ間もないです
>>746 >Windows98
そんな過去の遺物を使うのはやめなさい。
>マクロでPCのシャットダウンはできるのでしょうか?
WinAPIを使えばできるはずですが。
>あと、MsgBoxをのバックを画像にすることは出来ますか?
日本語でOK。
749 :
746 :2008/08/09(土) 13:43:59
>>747 メッセージボックスの背景を画像にしたいのですが、できますか?
よろしかったらマクロのやり方を教えてください。
>よろしかったらマクロのやり方を教えてください。 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#
756 :
y :2008/08/10(日) 12:04:40
>>753 線分を消す部分のコードだけで構わないので、あなたが書いたものを貼ってください。
それに加えて、何番目の点と何番目の点の間の線分を消すつもりだったのかと、
その意に反して、どの線分が消えてしまったのかも書いてください。
ぬるぽですか
y消えろ
759 :
デフォルトの名無しさん :2008/08/10(日) 13:39:51
>>753 訂正します。
>しかしExcel2003で開発していたのですが、
>Excel2003では異なった場所の線が消えていました。
Excel2003で開発してExcel2002では異なる結果でした。
Excel2003でコード実行し計算した結果グラフをファイルに保存し、
それをExcel2002で見るだけで異なる線が消えている。。。
またExcel2002で見た(異なる線が消えている)グラフを、再度Excel2003で見ると正常になる。
どうもグラフの順番のつけ方?の定義のようなものが異なるのではという感じがします。
コードのせいではないと思います。
しかしコレでは駄目なので。。。うーん悩ましい。
本人に悪気はないんだろうけど、コテハン使うなら、 他の人がせっかく答えてるのに、被せて回答するのはやめた方が良い。 他の答えてる人の面目丸潰れだよ。 んでみんな答える気が失せて行く。
本人を特定できるコテつけて発言してるなら別だが 名無しで面目もないもんだ
IDもでないしね
>>760 こういう手法もある、とか提示してくれる分にはいいんでない?
セオリーや最短の方法イコール最善の方法、になるとは限らないし
傍目でROMってる人のレベルにうまくマッチする場合もあるしね
勉強のために答えてるんだから大目に見てやれよ それに他の人の面目が潰れるほどの良回答はまだまだ出来てないじゃん 彼に面目潰されるようじゃ、潰された方がレベル低すぎってものだ
マターリやりましょ。 しかし最近は外部関数呼ぶ話が増えてきましたな。
766 :
y :2008/08/10(日) 21:14:24
>>759 そうなんですか。失礼しました。
うちには2003しかないので、残念ながらその状況を再現できません。
2002のほうで、2003で実行したのと同じコードを実行するとどうなりますか?
やはり2003とは異なる線分が消えてしまいますか?
グラフの書式の仕様というと、Excel的にはとても大切なところなはずなので、
バージョン間でそう簡単に定義が変わるとは思えないのですが...
>>759 一度2002でもマクロの記録でやってみれば
それでコードの問題かわかるだろ
TMR!TMR!
769 :
デフォルトの名無しさん :2008/08/11(月) 09:02:55
>>767 2002はもっていないんです。
使用者からのバグ報告なので。
770 :
y :2008/08/11(月) 19:08:16
>>769 2002で試せないなら、残念ですが私はもうお手上げです...
VBAと関係ない話なんでスルーしてもらって構わないんだけどさ。すごく気になったんで。 バージョンが多数存在するソフトの場合、金取って受注するならば、 可能な限り古いバージョンまで持っておかないとダメだよ。 金取って作業するならば、鉄則なんで。
Windows95サポートですね、判ります。
OSって意味じゃない。
> バージョンが多数存在するソフトの場合、金取って受注するならば、 > 可能な限り古いバージョンまで持っておかないとダメだよ。 そんなことは無い クライアントの発注要項に対応できるバージョンが揃ってれば問題ない 逆に考えれば、所有する環境で対応出来ない要項の発注は受けなければ良いだけ プログラムに限った話じゃないが、自分(自社)に何が出来て何が出来ないのかを把握して それに見合った受注をすれば良い、これこそが鉄則 設備、環境、能力以上の受注をしてしまうのは愚の骨頂だが、 何でもかんでも揃えようとするのもまた愚かしくある もちろん、事業拡大、売上向上の為には良い設備環境を整えるというのは大事だが 「可能な限り古いバージョンまで持っておかない」と、金取っての受注が一切出来ないわけでもないし 「可能な限り古いバージョンまで持っておく」ことが、金取って受注する上での鉄則でもない それと、VBAの場合はOSも関係有るよ Office(Excel)自体もOSのコンポーネント使ってるし、VBAからはCOM、Win32API、OCXなど 様々なOSのコンポーネントを任意で呼び出せる 故に、当然ながらOffice(Excel)のバージョンが同じでも、OSが変われば結果も変わることがある 場合によってはOSのSPが変わっただけでも影響があるくらいだからな
775 :
デフォルトの名無しさん :2008/08/11(月) 23:33:16
別bookの「ホゲ.xls」が開いてればそれをアクティブに、開いてなければ開くというコードを教えてください。
>>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 水 : :
>>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)
最近勉強し始めたばかりなので 初歩的な質問かもしれませんが ヒントください。 オートフィルタの抽出で 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
にするといいでしょう。
>>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
もっと効率的な方法で書ける方もおられると思いますが...
それと、マルチ(複数のスレッドで同じ質問をすること)はしないようにしてくださいね。
どなたかプログラマ向けの難しめのVBAの書籍(洋書でも可)を御存知ないでしょうか。 Excel Hacksとかではなく、VBAやらCOMとの絡みなど詳細な事項などが書いてあると嬉しいです。 いざ勉強しても何か心許ない感じになってくるので、 Oreilly的な本を一冊読んできちんと理解しだいです。 御存知でしたら、助言お願いします。
y大人だなぁ
COMってのは不特定多数が制作しているものだから
MSが作ったCOM以外を書籍で解説することはまず無いし
MSが作ったCOMに関してならMSDNにも情報がある
そしてExcel VBAに関しては、
>>1 ★3にも有るとおり
Excelの操作をGUIではなく言語でやってるだけであり
突き詰めたところでそう難しいものでも無い
その先を行きたいならVBAではなくVBの範疇になるので
VBの書籍を買え
>>789 すみませんが、VBでもいいので、
VB6互換の環境について、書籍を御存知ないですか?
791 :
デフォルトの名無しさん :2008/08/13(水) 02:37:31
vb6ってたとえば関数のオーバーロードとかクラスのインヘリットとかがない等、 C++とかに比べて言語仕様自体に機能が多いわけじゃないから、アルゴリズムさえ コードにできればリファレンス読むだけで十分な言語なんですよね? 高度な書籍っていっても結局vb6の機能をフルに活用して何が出来るかとかいう書籍がほしい んだったら、結局vb6からAPIやCOM使ってなんかするサンプルコードなんかが沢山載ってる本 をほしいって事と同じようなものだと思うから、結局vbの枠で書籍を探すよりも、むしろ COMの本買うとか、めんどくさいからvbやめて別の言語に手を出して、C++詳説の本買うとか しないといけないんじゃないかなぁと思うんですが。どうなの?
793 :
792 :2008/08/13(水) 02:48:23
古い言語といっても、まあ、新しいわけだけれど、
陳腐化したといったほうがよかったかな。
>>791 さん、お付き合いありがとうございました。
VBA上級テクニック なんちゃらって本があったな。 API関数やVBSの呼び出し方が解説してあってよかったかも。 ただ、具体的なAPI関数についての説明なんかは当然なし。 当時、具体的な呼び出し方が説明してあるのは役に立った記憶があるよ。 あと、何で変数の型が必要か、とかrangeの概念なんかも詳しく説明してあった。 それまで全部variantで使ってた変数の型も、きっちり宣言出来るようになったし、 何となく使ってたfor eachも、何がどう動いてるのかが理解出来たよ。
Range以外は全てVB6分野の話だな
InputBoxを使った入力について教えてください。 セルのコメントをInputBox関数で入力させるマクロを組んでいます。 この入力値を、任意の箇所で改行したいのですが、できますか? 可能な場合、InputBox関数で呼び出される入力ダイアログボックス にはどのように入力すれば良いのでしょうか? ご教示お願いします。
どうしてもInputBox使いたいなら、任意の文字列を改行として扱うしか無いかな Dim strTemp As String strTemp = InputBox("改行したい部分に\nを入れてください。", , "1行目\n2行目\n\n4行目") strTemp = Replace(strTemp, "\n", vbCrLf) MsgBox strTemp 改行扱い文字列は、別に\nじゃなくても本文中に出現しないものなら何でも良い でも、ユーザーフォームで複数行入力できるダイアログを作るのが正攻法だろ
できました。Replaceすればいいのですね。 ありがとうございました。
Aというシートからユーザーフォームのテキストボックス(10個ぐらいある) に入力された内容に従ってデータを抽出して 既存のBシートに貼り付けるような比較的長いコードを作りました。 最終的には、もしユーザーフォームの 「新規シートを作成して貼り付け」という チェックボックスにチェックが入っていた場合は Cシートを新たに作成し、そこにデータを貼り付け さらにDシート・・Eシートとシートを増やせるようにしたいと 思っています。 その場合は 現在作ってある長いコードを使って if checkbox1 = true then worksheets.add 「新しいシートに貼り付けてね」という長いコード 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 else 「シートBに貼り付けてね」という長いコード end if という風に、指定するシートを変えるだけで ほとんど同じコードを2回記述するしか方法はないでしょうか?? もっと完結にできる方法があれば教えてください。 モジュールがやたら長くなって見にくくなってしまうのを回避したいです。
>>799 共通する部分の処理でプロシージャを作り
Callで呼べばいい
>>800 ありがとうございます!!
さっそく試してみます。
ステートメントを早くいろいろ覚えないと
後で「こんなステートメントあったんだ!じゃぁあの時
もっと簡単にプログラムできたじゃん!」って思うことが多いです(;;
もっとよく勉強します。
本当にありがとうございました。
>>801 >後で「こんなステートメントあったんだ!じゃぁあの時
>もっと簡単にプログラムできたじゃん!」って思うことが多いです(;;
それが糧になるんだよ。決して無駄にはならないさ。
# 仕事なら話は別だが。
アクティブシート上にあるすべてのボタンを消去するのって ActiveSheet.Buttons.Delete じゃ駄目なんですか? いくら実行しても何も起こらないんですが。
画面に向かって「消えろー」って10回叫べば消えるかも
for each
>>803 ゙ボタン゙と言っているのはオートシェイプ?マクロ用のボタン(名前忘れた)?
>>806 オートシェイプです。
すいません、今調べたら
ActiveSheet.DrawingObjects.Delete
という命令でシート上のボタンはすべて消せることがわかりました。
追加で質問なんですが、一行目に配置されたボタンだけを残し、二行目以降のボタンをすべて消去する方法ってありますか?
>>807 プログラム化するならわからんが、オブジェクトの選択(矢印の付いたアイコン)
で範囲選択したら、その領域内に含まれる図形は全て選択できるからデリートで消す
>>808 デリートでセルを消してもそのセル上のボタンは幅が0になるだけで線になって残りません?
完全に消去する方法が知りたいのですが。
>>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数だけループ という方法でなくもっといいのはありますか?
CountIf
>>811 おいらならオートフィルタで指定の顧客名を抽出して、
if (cells(i,2).value = cells(i+1,2).value) daisu++}
ってインクリメントするかな。
すいません。文法間違えました。 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
目的は別シートに貼り付けるため、なのです。 全体を集計するのであればピボットで済みますが、そうではなく 必要な部分だけ抜き取って(項目も無し)それだけ集計して貼り付けたいのです。 手作業ではコピー、貼り付けしたあと、台数を修正して余計な行を削除 なんですがこれを自動化したいだけです。 標準の集計やピボットを利用するには、項目行もコピーしてシートも新しくせねばならず また、完成した集計表では顧客名や製品名に勝手に空欄が出来てしまうので 使いたい形に修正するだけで作業が余計に感じます。
これはマクロの記録で十分対応できるレベルだろ
・選択部分を新しいシートにコピペ ・製品を軸に昇順に並べ替え ・製品名が変わるまで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は既に実施しております。
データの数とグラフの数が多いと遅くなると思いますよ。 オブジェクト数が多いと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ですがよろしくお願いします。
第一要因
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)で配列をシートで見たけど合ってた。
ちょっとこれから会社なので、夜にまた試してみるよ。
最低限、君が書いた例通り、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でタブを作るのは無理ですか?
へるぷみー。 テキストボックスに入力された名前を 新規のワークシートに付ける際に、例えば「あいうえお」という 名前のシートが既にあるにもかかわらず テキストボックスに「あいうえお」と書かれた場合は 自動で「あいうえお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検索してみたりしたのですが 解決策が見つかりませんでした。 よろしくお願いします。
>>833 どこがVBAの質問なんだか。単純な名前生成の問題じゃないか。
毎回シート名に"n"を継ぎ足すんじゃなくて、都度入力された名前に"n"を継ぎ足せばいいだろ。
オブジェクト変数を使いまわすんじゃなくて、一時変数で処理する癖をつけた方がいいな。
>>832 何のタブかわからんが、ブックのタブならツールバーで作る手がある
836 :
デフォルトの名無しさん :2008/08/15(金) 18:48:16
>>832 ユーザーフォームでタブを云々ならマルチページなりタブストリップなりをコントロールから追加
837 :
デフォルトの名無しさん :2008/08/15(金) 19:03:27
ひとつのシートに複数のタブブラウザーみたいなのを作りたいと思っています。
複数のシートにしちゃいけないの?
839 :
デフォルトの名無しさん :2008/08/15(金) 20:10:50
ひとつのシートに複数のタブじゃないとダメなんです。できませんかねぇ。
わざわざシートタブがあるのにそれを使わずに更にタブをつける理由も抜きに、「できませんかねぇ」じゃねぇよ。
やろうとすれば出来るけど面倒
842 :
828 :2008/08/15(金) 20:21:18
>>831 たびたびありがとー
朝はバタバタしててできなかったけど解決しますた^^
ご指摘のとおりにFor文は0〜1にした方がすっきりしますね。
教科書とか読むとほとんど1〜だったのでなんか理由があるのかと
なんとなくこうしてました。
これで行列のいろんな演算ができそうです。
感謝、感謝
843 :
デフォルトの名無しさん :2008/08/15(金) 20:38:15
ひとつのシートにタブを複数にする理由は本当はプログラムを組んでPOSシステムみたいなものを作りたいのですが知識がなく、それをExcelでと考えています。面倒でも構いませんから教えていただきたいです。
845 :
デフォルトの名無しさん :2008/08/15(金) 21:33:42
>>842 配列についてはExcel VBAのヘルプで Option BASE で検索してみて
>>843 ボタンをタブに見立てて仮想的に実装すれば良い
これで解らないなら君には無理
諦めるか金払って作ってもらえ
847 :
828 :2008/08/15(金) 22:03:14
>>845 Option BASEで配列の最小値を0か1に選択できるのか
これは便利だわ
さんくす!
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 の影響を受けません。
>>834 ありがとうございます!
一時変数なるものについて勉強してから
それをヒントにもう一度よく考えてみます。
それは「期待通りに機能しない」とは違う。 プログラムに置いて「期待通りに機能しない」というのは、 仕様書きに反する結果を返す場合などに使用する言葉。 「仕様通りに機能しない」とほぼ同義である。 Array、ParamArray、SplitなどがOption BASE 1の影響を受けないのは、 確立された仕様で常に同じ結果になるので、これが思惑通りじゃなかった場合は 「間違った期待をしていた」ということになる。 仕様を間違って覚えていたら、思惑通りに動かないのは当然のことだからね。
852 :
y :2008/08/15(金) 23:33:36
あ、なるほど。その通りですね。
別にそこまで字面にこだわるようなものじゃないと思うが。 期待通りに機能しない、というのは単純に使用者が想定しがちな 一貫性を提供しない、ということだろう。
854 :
z :2008/08/16(土) 00:21:47
Application.Application.Application
OPTION BASEってプロシージャで1回しか宣言出来ないのがなぁ。 ま、OPTIONだから当然なんだけどね。 他の言語はあまり数知らないけど、配列で0からスタートしない言語ってあるのかな。 2系列しか言語知らないけど、配列は0から始まる。って覚えてるから違和感はないな。
>配列で0からスタートしない言語ってあるのかな 最近のCOBOLは違うかどうかまでは知らんけど、少なくともCOBOL85は1からスタート
857 :
828 :2008/08/16(土) 07:38:49
>>848 ご忠告ありがとー
Opttion BASE 1だと配列に格納する場合の添字と
配列から取り出すときの添字の値が同じだし、
行列の添字が一致するので便利と思ったけど、
使うときは注意したいと思います。
最終的には数千の行列を計算したいので逐一指定だけでは大変かと
思っていたけど、初心者の私にはまずこれでやってみます。
>>849 yさんありトンです
過去レスで配列のこともいろいろ書かれてますが
読み返すと少しずつ分かってきました。
Array関数などはまだ使ったことがないけど、
使うときにはOption Baseに添字が影響されないことを思い出します。
皆さん大変勉強になりました。初心者の質問に真摯に対応していただいて
なんかうれしいです。ありがとうございます。
VBが嫌なのは普通に長さ0の配列を作れないこと
ちょっと古い質問ですまんが、
>>736 の
>> Const DATA_N As Integer = 50
>数値型、文字列型の定数で型指定するな
これってどういうこと?
Const DATA_N = 50
の方がいいってこと?
860 :
y :2008/08/16(土) 11:58:13
>>858 長さ0の配列って、どんなことに便利なんですか?
アイテムを持っていないCollectionのようなイメージでしょうか。
>>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の理屈からすれば正しいのかもしれないですが、たしかに普通じゃないですね。
VBAならEnptyでいいのでは?
JAVAあたりだと、配列数をredimする必要もなく、どんどんputして行けるんだよね。 それが良いとは一概に言えないけど、VBだとそこらへんが不便。
Enpty?
>>864 たぶんjava.util.List<E>のことを言っているのだと思うが、Javaでも
配列じゃダメ(というわけでもないがReDim無いので相当に面倒)だがね。
VBは標準でDictionary揃えていないあたりコレクションの取り扱いが面倒。
は?コレクションならあるだろ
エンプティダンプティ
>>867 コレクションっていうのはJavaでいうコレクションのことね。
SetやらMapやらQueueやら。
アホが
Jamaだよ
872 :
デフォルトの名無しさん :2008/08/17(日) 00:35:10
設定としては再計算を自動にしているのですが、マクロでやると、 エクセルのコマンドバーに「再計算」が表示されます。そこを自動にするため、 SendKeys "{F9}", True を書いてみたものの何の役にも立っていません。 どのようにしたら、いいでしょうか? ご教示願います。
年月日時間の計算なのですが、 VBAで hoge = cells(1,1).value - cells(1,2).value とすると型が一致しないと怒られますが、 ワークシート関数で、 =A1-B1 とやると、うまく計算してくれます。 ワークシート関数にはVBAには無い自動整形機能などが付いているのでしょうか。
言い方がおかしかったです・・・・。 どんなVBAの機能で計算されているのでしょうか。
>>872 Sheet.Calculate使えばいいでしょ
>>873-874 そもそもVBAとExcelの演算はぜんぜん別物。
Excelの計算はVBAの機能などではない。
あー、わざわざ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
879 :
872 :2008/08/17(日) 02:52:19
2003 XPです。 再計算はされていません。再計算に続けてワークシートイベントのcalculateが 動くようにしているつもりなのですが、再計算のために手動でのF9キーを 押すと、きちんと再計算後のイベントが働き、目的が達成されます。 ただ、今日は、状況、目論見等の説明がうまく書けてないので、また、来ます。 夜遅くに、ありがとうございました。
880 :
デフォルトの名無しさん :2008/08/18(月) 17:05:33
すみません。ご指導お願いします。。 100万行以上あるテキストファイルを、1万行づつ分割して 元のデータの形式、区切り文字、列のデータ形式 を指定し、エクセルシートに取り込んむVBAは可能でしょうか? 可能であるならどのようにしたらいいのでしょうか?(Accessは使わず) 宜しくお願いします。
882 :
y :2008/08/18(月) 18:54:52
>>880 偶然ですが、ちょうど私も500万件の氏名+ふりがなデータを使って
似たようなテストをやっている最中です(遊びで)。うちの場合は
1シートあたり5万行ずつで100シート分です。理屈としてはできるはずですが、
途中何が起こるかわからないので「可能です」とは言えません。
テキストファイルの取り込み方は、まず「テキストファイル VBA」とかで検索してみてください。
たくさん出てきますよ。
>>880 Excelのバージョンによらない解決法は、
1. テキストファイルを順次読み込み、1万行分のファイルを作る
2. Excelの機能でテキストファイルを読み込む
3. 読み込んだシートをBookのシートにコピー
4. 1にもどる
>>882 どう考えても「可能」だろ。
適当なこと言うなよ。
名前とふりがなで1件50バイトとして5万行で2.5MB 100シートだから250MB おれはexcelで30MB以上のファイル開いたことないなー
Excelにデータを読み込むのが目的じゃなくて、読み込んだデータを何かに使うのが目的じゃないのか? だとしたら、SQLiteとかの方がいいかもしれんぞ。
いや、だったらmdbでいいだろ
888 :
y :2008/08/18(月) 20:35:22
>>884 あ、可能なんですね。失礼しました。
こんなに件数が膨大だと、メモリの関係で途中で止まってしまうとか、その他不測の事態が
起こったりしないとは言い切れず、従って「可能」とも言い切れず...みたいな心境でした。
氏名生成を16:00頃に開始して、今でようやく400万件です。
テキストファイルで120Mbになっています。どうなることやら...
というか、excelに向いてる事、向いてない事を考えろよ。 出来る。と向いているは全く違うぞ? yみたいに遊びで試すなら何やっても良いけど、 仕事で使うなら、excelで大量のデータ処理をするなんて考えは捨てるべき。 と思ったけど、yは500万件の氏名データ持ってる時点で遊びじゃない。 もっと色々と自覚したほうが良い。
>>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
Excelの仕様くらい調べてくれよ・・・
何勘違いしてるの?
どうしてもExcel VBAじゃないとだめなん? 今時珍しいぞあんな低速言語
yが来るようになってから、このスレが変になった
依存するのは物理メモリか?
>>880 は特に「単一のブックで」といった事は書いていないようだが
その辺は暗黙の了解なのだろうか
899 :
デフォルトの名無しさん :2008/08/19(火) 11:22:06
みなさんありがとうございます。。 補足させてください。 フォルダの中に複数のテキストファイルがあります。 それをVBAで1シートに1テキストファイルづつで取り込んで (区切り文字(#)、列のデータ形式(文字列)を指定して) 作成済みのマクロを実行し、出力させたいのですが。。 データが大きいので5シートで1つのファイルにしたいです。 フォルダの中にはテキストファイルが100ほどあるので、結果、エクセルファイルが 20できればいいのですが。。 できればデスクトップに新しいフォルダが作成されて その中に出力されていくようにしたいです。 お力を貸してください。よろしくお願いします。
現在、ユーザーフォーム上でワークシートを表示させるべく スプレッドシートを設置することはできましたが、 このスプレッドシート上にチェックボックスを表示させる方法が分かりません。 何か良い方法があれば教えてください。お願い致します。
>>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 お前の方が癇に障って癪だわ。お前が消えろ。
自作自演ヒドス
匿名掲示板でコテハンを長く名乗るって事は、それだけのリスクがあると言う事。 自分の向学の為ならば、コテを名乗る必要はどこにもない。 仮に間違った事を回答したとしても、責任なんてない。逃げるのも簡単。 それが匿名掲示板だから。 自分で退路を塞ぐだけでも愚かな事なり。
そんなのどうでもいいわ。ここはExcel VBAのスレだろ
コテハンがそんな大層なもんかね 何か勘違いしてるんじゃないの
退路っていうのは間違っても訂正しないことなんだろうか
荒れてますな〜w
916 :
デフォルトの名無しさん :2008/08/21(木) 08:41:58
すんません。質問させてください。 違う部署の人にヘルプを頼みまして、条件に合致する物にフラグを立ててくれたんです。 後で処理するんで、文字列の最後尾に記号をくっつけといてもらったのですが、 よりによって、アスタリスクが最後尾に付いてました。 適切に指示しなかった私が悪いと思い、今後は別の記号か、 別のセルに数字でフラグを立ててもらう事にしたのですが、 そこで質問です・・・。 autofilterも、replaceも、*はワイルドマークとして機能しているようですが、 エスケープシーケンスは存在しますでしょうか。 文字列としての*を判定させたい場合の処理などが可能でしたら教えてください。
[*]
ありがとうー
920 :
デフォルトの名無しさん :2008/08/21(木) 21:59:10
質問です。 他のxlsファイルを読み込んでいろいろ作業するのを、マクロの記録からやると 切り替えごとにWindows("hoge.xls").Activateになりますよね? これだとファイル名を変えると動かなくなるのでなんとかしたいのですが 元の方はThisworkbook.Activateに置き換えすると済みますが 相手ファイルも同様に使いやすくするにはどうしてますか? GetOpenFileで指定したファイルをどこかの非表示セルに書き込んで それを読み込む方法しかないのでしょうか? 他にいい保存場所ないのかなぁ?
起動中のエクセルファイルには、起動順に番号が割り当てられている。 ファイル名を指定しなくても、 Workbooks(n).Activate (nは数字)という形で、n番目に開いたファイルをアクティブにできる
一時的にマクロを停止させ、 その間にワークシートを操作するプログラムを組みたいのですが躓いています。 waitメソッドを使えば実現できるかと思ったのですが、 マクロは停止するけれどもワークシートが操作不可能です。 実現するべく何が良い方法があればご教授ください。
doevents
>>920 hoge=Activexworkbook.nameで開いたファイル名を取得
コントロール配列使えないVBAももうちょっと頑張ってくれればいいのにな。 vbe.netとかつくって欲しい。
926 :
920 :2008/08/21(木) 22:32:10
>>924 それだと毎回ダイアログ画面で指定しなきゃいけませんよね?
ファイル名を変えちゃったときに、一度指定してもらうだけで済ませたいのです。
927 :
y :2008/08/21(木) 22:48:28
>>926 非表示セルか非表示シートのセルでいいのでは。
個人用マクロブックとか、外部テキストファイルとか、いろいろ考えられますが、
複雑になるだけだと思うので。
総合スレよりこっちの方が良さそうなのでこちらで質問します。 ワークシート上に配置したコンボボックス(フォームではなくActiveXの)に初期値として、 今日から5日前〜今日から10日後の日付をセットしたいのですが、うまくいきません。 ユーザーフォームだとUserform_Initializeの中に記述すればいいんですが、 同じ様にはできません。どうすれば良いでしょうか。 clickイベントでも試しましたがコンボボックスはchangeイベントしかダメなのかな?
>>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というものしか出てこず離れたところにコピーするやり方が分かりません。 すみませんがご存知の方教えていただけないでしょうか
>>931 Range("C10").FormulaR1C1 = Range("C5").FormulaR1C1
>>932 ありがとうございます
意図したことが出来ました
VBA使って関数や数式のコピーってどうなのよ。 モジュールに数式書いてくれればすぐわかるのに、 数式のコピーって、いちいちプロパティで調べないといけないから面倒なんだけど。 なんでそんな事するの?死ぬの?
呪殺予告きたー! これは逮捕だな
>>934 の言っている意味がわからない。
数式コピーされると死ぬの?呪殺されちゃうの?
なれないVBAで苦労しているのですが、オートシェイプ周りの制御はどうすれば 良いんでしょうか。移動や変形どころか、アクセス方法すら分からずじまいで。 取っ掛かりだけで十分なので、教えていただければ幸いであります。 流れ読まずにすまんですたい。
なにがしたいの?
940 :
側近中の側近 ◆0351148456 :2008/08/23(土) 22:09:37
>>938 (っ´▽`)っ
マクロの記録でやってみればいいじゃん
>>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にするのどっちが効果的ですか?
真逆の選択肢に見えるのが面白いw
946 :
y :2008/08/23(土) 22:50:05
>>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 のように、数式がソース上どこにも出てこないことになるから。
>>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))
>>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゚∀゚)ノ゛
VBAで課長の背骨をヘシ折る事は可能? あと、栗とか剥ける?VBAで。 ググッても全然HITしない。
ああ、できるよ。
>>956 ありがとう
一応名前付き範囲は知ってるよ
君はのりのりですごい親切だね
また今度教えてね
うぜーよ
>>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で吐血する?
そのコードじゃ無理だけどな
VBAでルーチン組んでから、椅子で殴れば良いじゃん。
ハードディスクのデータをクリーンにするプログラムを組んでプレゼントしなさい。
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
を削除しましょう。
970 :
デフォルトの名無しさん :2008/08/24(日) 14:41:12
CSVファイルの数値を分析したいのですが フォルダ内すべてのCSVファイルにマクロを実行する方法はありますか? 紹介されている本やHPを教えていただけませんでしょうか? よろしくお願いします。
うーむ・・・CSVってカンマ区切りのデータテキストの事だよね? 一度EXCELに読み込んで処理じゃダメなのかな。
このスレ的にはそれがいいね。 どうやってやるかは、マクロ記録すればすぐ判ることだし。
excelで普通によみこむと、おもってるのと違う動きされることあるんだよなー。 だから、俺は、1行ずつ読み込み、コンマで区切りごとのデータを自前で配列にいれる 多バイト文字つかわれてたりするとこは、1フィールドごとにエンコードチェック、 をずっとEOFまでやってから、自分のおもってる型にかえてから処理しとる。
974 :
y :2008/08/24(日) 22:14:08
「フォルダ内すべての」CSVファイルに対して処理をしたい、 という点でもつまずいているのかも。それについては、 「FSO」を検索すると役立つ情報が見つかると思います。
CSVの定義って厳格な物ある?ファイル形式とか。 気になって調べたんだけど、ファイル形式までは規格されてないような。 んで、フォルダの中身全部、って指定がかなり難しいのではないかなと。 たとえば拡張子がtxtだとしても、それがCSVで組まれたデータファイルなのかは、 計算機で判断出来るの?って思ってさ。
RFC 4180
基本的に、顧客が好むのが、Excelでひらいたときにどうみえるか。 なんで、 "dataA", "dataB", ... , "dataX" みたいに、""でかこむことになる。 数値解析とかだけのローカル用途なら、囲まんけどな。
FSOの.Filesでファイル一覧取得して、Right$で.csvだったら、 FSOの.Readallで読み込んで、VBCRLFでSplitして、 配列に入れて配列をカンマで、Split
プロジェクトのこまごま作業で多かったのがFSOによる再帰ファイル検索だ
"abc,def","ghi","""" ってな感じのデータに対応しようと思ったら面倒よ、自前でやるのは
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データは、シングルクォーテーション('')で囲まれたタイプのも
ざらにあるので意外と厄介ですよね。
Dir(fPath & "\*.csv", vbNormal) Ifはいらない
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で実現してくれるコードを教えてください。
マクロの自動記録でいいんじゃないの
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 (っ´▽`)っ
ウォッチウィンドウでそれっぽいプロパティを探せ☆
>>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
これで透明になるよ 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ではどうやりますか?
うちはXMLに統一してるんでCSV時代のトラブルは一切無くなったな。
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を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。