1 :
デフォルトの名無しさん :
2010/11/08(月) 11:13:57
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Sub Macro1() SendKeys ("%{F11}") st = 100 'Top ボタンの初期位置 sl = 200 'Left dt = Range("B2").Top '移動先 dl = Range("B2").Left ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False, DisplayAsIcon:=False, Left:=sl, Top:=st, Width:=64, Height:=32).Select Sleep (500) nw = 30 For i = nw To 0 Step -1 Sleep (15) Selection.ShapeRange.Left = dl - (dl - sl) / nw * i Selection.ShapeRange.Top = dt - (dt - st) / nw * i DoEvents Next Sleep (750) End Sub このコードで、 動かすもの"コマンドボタン"を"図1"に代えたいんですがどうすればいいですか?
4 :
デフォルトの名無しさん :2010/11/08(月) 17:01:00
ExcelのVBAに関する質問スレです ★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 レベルはどうあれ、ここはプログラマ用の板スレです。プログラマとは、自分でプログラムを組み コードを書く人の事なので、自分でやるきは全く無く、丸投げしようって人はお断りです。 ヒントを貰えばあとは自力でなんとかしますって人のみどうぞ。 ★6 わからなければとりあえず「マクロの記録」(Alt, T, M, R)
>>3 ActiveSheet.OLEObjects.Addでボタンを作った直後にこれを入れる
Selection.Object.Caption = "図いち"
>>5 すいません、そういう意味じゃなくて
ボタンを動かすんではなく、他のもの(ここでは図)を動かしたい
という意味です
ずいぶん初歩的なこと聞いてた 事故解決しました
8 :
7 :2010/11/08(月) 18:38:33
事故→事故でしたすいません
こんどは
>>3 で動かすとき図形を下に来るにつれてどんどん大きくしたいんですが
(ボールがこっち側に飛んでくるイメージ)
このやり方を教えてください
お願いします
>>8 Widthプロパティでコントロールの幅、Heightプロパティで高さが指定できる
っていうか、完全にExcelの間違った使い方だな
いいんじゃない? マージャン作る奴もいるわけだし
11 :
7 :2010/11/08(月) 21:05:18
12 :
7 :2010/11/08(月) 21:27:08
ActiveCell.Row でアクティブセルの行数が分かりますが、"図1"の現在の行数を求めるにはどうしたらいいんですか?
>>12 TopLeftCellプロパティとBottomRightCellプロパティ
配列A内の値が同じA内に重複している事もある それをユニークにしてダブりをなくす、ユニークにする関数ってある?
17 :
デフォルトの名無しさん :2010/11/11(木) 22:14:11
csvをtxtに変換するマクロを作成しました。 現在は、Cドライブ直下のみで動作するようになって いますが、ファイルがどこにあっても動作する ようにしたいと思っています。 教えていただきたく、よろしくお願いします。 csvをtxtに Macro Dim myOldName As String Dim myNewName As String Const myOldDil As String = "*.csv" Const myNewDil As String = ".txt" Const myDir As String = "C:\CSV変換\" myOldName = Dir(myDir & myOldDil) While myOldName <> vbNullString myOldName = myDir & myOldName myNewName = Left(myOldName, Len(myOldName) - Len(myOldDil) + 1) & myNewDil FileCopy myOldName, myNewName Kill myOldName myOldName = Dir() Wend End Sub
プログラマですがエクセル初心者です Excelで作ったデータを、csvに保存してブラウザでアップロードすることでDBに登録しています。 これを直接、Excelからサーバーにアクセスしてデータを上げることはVBAで可能でしょうか?
21 :
17 :2010/11/11(木) 23:13:38
>>18 >>19 早々のご回答ありがとうございます。
どちらも思い通りになりました。
>>20 可能
vbaでhtmlもJavaScriptもSQLも書ける
でも普通にvbaからJAVA呼び出すのが普通かと
>>20 ちなみに、VBAから呼び出せないプログラムの方が少ないような気がする。
少なくとも俺の使える有名言語は、全てVBAに直書きが出来てる。
ほんま恐ろしい言語やで、VBAは。
24 :
デフォルトの名無しさん :2010/11/14(日) 18:30:08
ExcelVBAでADO使うのが一番普通じゃね?
>>20
延々と続く作業をやってるとスタック容量?が足りないとか言われるけど、解決する方法教えてほしいです まあ解決というか終了したあと勝手にまた同じマクロを実行する方法 知恵さえ絞れば出来そうなんだけど
Doevents ?
>>25 スタック不足の原因の一つとして、そのマクロに何か欠陥がある場合もある
メモリの増設とか64bit版に乗り換えるという方法もある
エラーで終了したあと自動的にマクロを再起動するのはVBAだけだとちょっと難しいかも
時々セーブする
Excelのパスワード入力なしで開くのを頑張ってた人です 無事解決しました vbaすら不要でスレ違いなのですが一応報告です xlsのファイルオプションでvbsからbookをパスワード付きで開く処理追加しただけ パスワードなしのbookもそのまま開けるので、これにて終了です 回り道した割りにあっさりできました でも、色々とスレ住人には世話になりました感謝です。ありがとう ま、ウィンドウ毎にブックが開いてしまうので、こいつを制御できないモノかと
GetObjectしてエラーだったらcreateObject
>>29 おかえり。ただ、意味がわからんw
ExplorerとExcel.exeの中間にVBScriptを配置したってことか?
拡張子.xlsの関連付けをいじって、呼び出し先をexcel.exeから自作のvbsに変更し、
そのVBScript内からExcel.exeを呼び出す際に引数で特定のパスワードを読み込ませるようにした、ということなのか?
だとすると強引なやり方だなw
それになんかの拍子(SPパックとかセキュリティパッチ当てた時とか)に関連付け外れる危険性はあるな。
でもまぁVBScriptの中身いじる事でパスワードの変化にも対応できるし、やろうと思えば複数のパスにも対応したりもできるし、
拡張性については十分確保してるか。わりと妥当な結論なのかもね。
ともかくお疲れさん。
32 :
29 :2010/11/17(水) 00:07:07
>>31 xls拡張子を実行時にvbs起動であってます
つたない文章でいつもすいません
ただ、今の状態だとブックを開く度にExcel.exeが上がってしまうので1つのexe内でブックが複数開けないか思考中
これもスレ違いなので、消えます
vbaの質問や議論にはいつも通り参上しますがw
30スルーかよ
34 :
デフォルトの名無しさん :2010/11/17(水) 10:03:44
質問させてください。Excel2010にて
csvファイルを読み込もうとするとき、ダブルクリックでBookとして開くと
住所などのハイフンが混ざった数字データが日付として認識されてしまって、
直そうにもシリアル値となってしまっているので正確に復元することは難しいです
かといって『外部データの取り込み』でテキストファイルとして全列のデータ形式を
文字列でインポートしても、同一項目内(要はダブルクォートで囲まれた中)に
改行があるとセル内改行とはならず行がそこでズレてしまい、使い物になりません
csvファイルを「そのまま」読み込んでくれるマクロ
http://homepage2.nifty.com/e-ka/win32/index.htm を使ってみても同じでした
どなたか対処法を教えていただけませんか?
マクロでシリアル値を元のハイフン付きの数値に戻せるのなら最高なのですが…
数値(列番号)から列文字(A,B,...Z,AA,AB,...)に変換する関数ってないですか? とりあえず今は力技で、 IIf(x>26,Chr(Asc("A")+(Int(x/26))-IIf(x Mod 26=0,2,1)),"")&Chr(Asc("A")+((x Mod 26)-(IIf(x Mod 26=0,-25,1)))) としてますが。。。
>>35 Replace(Cells(, x).Address(, False), "$1", "")
力業でやるにしても、式はもうちょっと簡単にできる
IIf(x > 26, Chr(64 + (x - 1) \ 26), "") & Chr(65 + (x - 1) Mod 26)
どっちにしてもこの方法だと3文字になったときに破綻するけど
>>34 もちろんマクロを作れば可能だけど、けっこうめんどくさそう
別の方法として、テキストエディタでハイフンを別の記号に置換、
Excelで読み込んでからマクロで元に戻すという手もある(残念ながら置換では戻せない)
でも、そういうマクロってよく探せばきっと誰かが作ってると思うんだけどなあ
Set mc = Worksheets(1).Cells(1, 1) MsgBox mc.AddressLocal() ' $A$1 MsgBox mc.AddressLocal(RowAbsolute:=False) ' $A1 てな感じでは?
>>34 ADOでMicrosoft.Jet.OLEDB.4.0ドライバ使えば csv は読める
ただ、Jet ドライバ使っても csv の読み込みはデフォルトだと、カラムの型を
自動認識してしまうので、schema.iniファイルを使って、全カラムが文字列型であることを
明示してやる必要があり、そのあたりが面倒だけど
40 :
626 :2010/11/17(水) 22:07:01
>>30 GetObjectして
エラーだったらExcelオブジェクトがないから新規にcreateObject
エラーじゃない時は既にオブジェクトがあると判断できるから
Getしたオブジェクトでbook開くって事?
41 :
34 :2010/11/17(水) 22:26:49
>>37 可能なんですか!3-17とか4-5-3とかハイフンの数がまちまちなので、
シリアル値に変換された後は戻すのが不可能だと思っていました
しかしどうすればちゃんと正しく戻せるのかさっぱりわかりません。限界か…
マクロは自分なりに結構探してはみたのですがどうも改行をうまく処理してくれる
ものが見当たらないんですよね。調べ方が下手なのかもしれません
>>39 ちょこっと調べてみましたが、私のようなへなちょこには敷居が高いですね…
43 :
デフォルトの名無しさん :2010/11/17(水) 23:11:43
質問があります。 osはXPでExcel2003を使用しています。 マクロで特定の行、たとえば1行目にある すべてのチェックボックスのみ削除することは可能でしょうか? 範囲を選択し、CheckBox.Deleteとするとシートにあるすべての チェックボックスが削除されてしまいます。 特定の行にチェックボックスを追加することはできたのですが、 削除がどうしてもできません。助けてください、お願いします。
>>43 CheckBox1.TopLeftCell.Row
で、そのチェックボックスが何行目にあるかわかる
1つ1つIfで調べて、1行目なら削除ってやればいい
エクセル2003です。 ユーザーフォームに30個のテキストボックスを30個設置しています。 全てのテキストボックスが空白のままOKボタンを押すと 「テキストボックスがすべて空白です」とエラー文が出る様にしたいのですが。。。 For myCnt 1 to 30 If "TextBox" & mycnt = "" Then MsgBox "全てのテキストボックスが空白です!何か入力してください" Exit sub Next myCnt とかやってもうまく行きません。 何かヒントあれば教えてください。
46 :
デフォルトの名無しさん :2010/11/17(水) 23:37:57
47 :
デフォルトの名無しさん :2010/11/17(水) 23:46:57
>45 逆じゃね? 空白じゃないテキストボックスが見つかれば 何か処理をしてeixt subする。 見つからないままforループが終われば、MsgBox \\\"全てのテキストボックスが空白です!何か入力してください\\\"
49 :
デフォルトの名無しさん :2010/11/18(木) 00:14:32
>>44 行を削除してもチェックボックスが残ってしまう・・・
特定の範囲にあるチェックボックス自体を
削除する方法はないでしょうか?
>>49 If CheckBox1.TopLeftCell.Row = 1 Then CheckBox1.Delete
>>42 thx
GetObjectなんて使うの初めてだわ
色々有り難う
>>49 カット&ペーストで一時的なシートに逃がすとか
EXCEL2003を使用しています ワークシート上に Label を10個とComboboxを1個配置します シート上のComboboxで1〜10の数字を選択し、1 が選択されると Label1 の背景色を黒色へ変えます。 同様に 2 が選択されると label2 の背景色を黒色へ変えます。 これを全10個のLabelで同様の動作をさせたいです。 Comboboxで選択された、 1 は取得できたのですが、 Label1 を選択する方法がわかりません Me.Controls("Sheets7.label" & 選択番号).BackColor = &H0 こんな風にやってみたのですが メソッドまたはデータメンバがみつかりません と出ます。 お知恵を貸してください。
ActiveSheet.OLEObjects("Label" & i).Object.BackColor = &H0
55 :
53 :2010/11/18(木) 16:52:42
>>54 ActiveSheet.OLEObjects("Label" & 選択番号).Object.BackColor = &H0
で出来ました!
ありがとうございます。
質問よろしくお願いします。 sub A() call B end sub sbu B() msgbox "aaa" 'call元のsub Aを終了させたい" end sub とある時に、callされたBのsub内で、call元のAを一発で終了させる事は可能でしょうか。 flgを立ててexit subも考えたのですが、VBAを全て停止させる構文があったら教えてください。
>>56 http://codepad.org/2B6Mifx1 call元のAを終了させる理由が分からないので何とも言えない。
1) SubプロシージャのAの(3)を実行させたくないだけなら新しくSubプロシージャABを作った方が早い。
2) 単にVBAを停止させたいならApplication.Quitを呼べばいい。
3) (3)を実行させる場合とそうでない場合があるならAを二つに分けてBの戻り値で判定してIf文で判定する。
入力ファイルを選択させる場合のデフォルトディレクトリ フォルダを選択させる場合のデフォルトディレクトリ それぞれ初回時選択した場所を記憶させることってできますか?
>>57 ありがとう。
私も他の人から質問されたので、なぜそんな構造になってるかが分からなかったんです。
やはり、構文構造から見なおした方が良いかもしれませんね。
60 :
デフォルトの名無しさん :2010/11/20(土) 10:54:37
>56 これってCodeModule.DeleteLinesでsubBの中からsubAを消しちまったらどーなるんだろ?
>>58 何したいのかしらんけど、記憶させるってことだけなら変数に保存しておけばいいだけの話では?
>>58 継続処理なら変数
そうでないならセルなり外部ファイルなりコード追記処理に記憶
>>58 static使うか、レジストリに記憶させるか、俺ならstaticから試すかなぁ。
>>60 一度実行されたコードはファイルを開き直すまで更新されないと思う
昔リロードさせたくて調べたけど全然わかんなかった
戻り先が格納されてるだけだから、Aに戻った瞬間にコンパイルエラー吐くんじゃなからか
>>60 Sub A()
Call B
Msgbox "AAA"
End Sub
とか
Sub A()
dim v
v=100
Call B(v) ●Bで、v*2
Msgbox v
End Sub
とかして、BでAをdeleteしてみたところ
AのMsgboxは正しく表示された。
>>60 の言うとおり。
ただ、
>開き直すまで更新されないと思う
開きなおすまで、という意味が分からなかった。
聞かぬは一生の恥、ということで教えてもらうと嬉しい。
Excel2007 Listboxコントロールって中に罫線表示というかgrid表示って出来ないんですかね? その他のコントロールでListViewコントロールを使わないと駄目?
>>69 ありがとう
今の私のレベルでは無理なんで、それは諦めます w
>>67 そのコード実行後にファイル保存&クローズすれば次に開いた時に変わってる。
だったかな?
質問です シート1にコマンドボックス シート2にコマンドボックス登録用データと登録ボタン(コマンドボタン) これでコマンドボックスにデータは入るでしょうか?
73 :
72 :2010/11/24(水) 15:57:58
ちなみに使用しているのは2007です
75 :
72 :2010/11/24(水) 16:33:35
>>74 ざっくりでいいので、手段を教えてくれませんか?
76 :
72 :2010/11/24(水) 17:07:21
別シートにコンボボックス表示用のデータを書くのではなく、 直接コードに書くようにしてみました。 Private Sub OsBox_Change() With OsBox .AddItem "Windows" .AddItem "UNIX" .AddItem "Linux" .AddItem "Solaris" .AddItem "AIX" .AddItem "RedHat" .AddItem "MacOS" End With End Sub 保存して、一度エクセルを落としてから再起動しても コンボボックス内に反映されなかったので、 コードを実行(F8キーでデバック?)してみました。 すると、コンボボックス内に項目が表示されました。 ただし、デバックを繰り返すと項目が2重3重に登録されてしまい 思ってた挙動になりません。 どうしましょうか?
MsgBoxのボタンにXPスタイルを使うことってできる? ボタンだけ古いスタイルでちょっと困っている。
78 :
デフォルトの名無しさん :2010/11/25(木) 08:05:47
79 :
デフォルトの名無しさん :2010/11/25(木) 09:22:57
Class_Terminateから例外をあげるとデバッガにとっ捕まるのは何故? 例外が伝播してくれないので終了処理できなくてとても困るんですけど。
80 :
デフォルトの名無しさん :2010/11/25(木) 09:33:51
ちなみにデバッガにつかまった後、「デバッグ」を選択するとRaise直前に 戻されて永久ループ、「終了」だとその場でプログラムの実行をするけど、 各種変数が初期化されてしまうみたいで超使えない。 まったく触っていないはずのプロパティが消滅しているので参ったわ。
>>72 Sheet1 にコンボボックス(OsBox)
Sheet2 のA1〜A7にOS名一覧
Sheet2 のCommandButton1でOsBoxに一覧セット
'-----------------------------------
Private Sub CommandButton1_Click()
Sheets("Sheet1").OsBox.List = Range("A1:A7").Value
End Sub
'-----------------------------------
>>76 コードの最初に、OsBox.Clear がないので質問のようになる
Additemを使うときは必ず入れるようにしておくとよい。
それよりも何よりも、Changeイベントでのセット拙いと思う、、
VBAの基礎がよくわかってないんだけど、 @ユーザーフォームにリストボックスを作成 Aリストボックス内に.rowsourceプロパティを使って、項目を作成 Bコマンドボタンクリックでリストボックス内のどの項目が選択されたかを MsgBoxで表示する この一連のマクロ?をエクセルシートを開いたときに実行するようにしたいんだけど 実際にはVBEで実行(F5)しないと実行できない。 何が足りてないんでしょうか?
This Workbookに openイベントとして書かないと
WAN側IPアドレスを引っ張る方法とかって有りますか? サンプル等があれば助かります
Excel2007です コンボボックスに複数列のデータを表示させるのはどうすればできるんでしょうか? ▼をクリックした時に2列のデータが表示はされるんですけど、行を選択すると左のデータのみしか表示されません。 ちなみにデータの格納はrowsourceではなく配列を入れています。 コンボボックスのプロパティで ColumnCountを2に設定してます。 Private myList() As String For i = 1 To UBound(structtbl) With structvertbl(i) myList(1, i) = .id myList(2, i) = .verdata End With Next Me.combo_data.Column = myList
87 :
デフォルトの名無しさん :2010/11/25(木) 18:18:31
excel2000です 素数判定をするプログラムです Sub 素数判定() num = Range("数") If num = 1 Then Range("判定").Value = "素数ではない": End If num = 2 Then Range("判定").Value = "素数": End On Error GoTo ErrorHelp w2 = num Mod 2 If w2 = 0 Then Range("判定").Value = "素数ではない": End For i = 3 To num / 2 Step 2 c = num Mod i If c = 0 Then Range("判定").Value = "素数ではない": End Next Range("判定").Value = "素数" Exit Sub ErrorHelp: Range("判定").Value = "計算が正しく行えませんでした。" MsgBox "エラー内容:" & Err.Description End Sub Rnage("数") に入力されている数を Range("判定") に判定をするのですが Range("数") の数が大きすぎるとオーバーフローしてしまいます。 いまはerrorgotoで処理していますがオーバーフローしないようにはどうすればいいでしょうか
>>87 変数の型をCurrencyやDecimal等のもっと大きな数を扱えるものにする。
それでも足りなければ多倍長整数演算ライブラリを使う。
軽くググった限りでは、VBA用にBigIntというものがあるようだが。
86です。 え〜っと、質問を一旦取り消しておきます。
ビジネスSoft板のExcel総合相談所より誘導されてきました。(94-563です。) まずは環境は以下のとおりです。 WIndows Vista / Excel 2007( Office 2007のExcel) (一部マシンにはXP + 2003が載っているものがある。) 質問は、イベントについてです。 実験のためのものなので、意味のない内容であることはご容赦を。 @実験の内容 Msgクラスのインスタンスからイベントを発行すると、 2つある別のクラスのインスタンスからそれぞれイミディエートウィンドウに メッセージを出すというもの。 ○標準モジュール ・宣言部 Msgクラスをとる変数を作成 ・Mainプロシージャ Msgクラスのインスタンス作成 Class1クラスのインスタンス・Class2クラスのインスタンスの作成 Class1.Aメソッド実行 ○Msgクラス ・Mメソッド イベントMessege(String)を発行 (続きます)
91 :
90 :2010/11/26(金) 01:59:45
○Class1クラス ・宣言部 Msgクラスをとる変数をPublic WithEventsで作成 ・Initialize 宣言部で作成したMsgクラスのインスタンスを代入 ・Messegeイベントのレシーバ イミディエートウィンドウに「Class1: 'Str'」を出力('Str'はイベントの引数) ・Aメソッド Msg.Mメソッドを実行 ○Class2クラス ・宣言部 Msgクラスをとる変数をPublic WithEventsで作成 ・Initialize 宣言部で作成したMsgクラスのインスタンスを代入 ・Messegeイベントのレシーバ イミディエートウィンドウに「Class2: 'Str'」を出力('Str'はイベントの引数) @結果。 実行するとClass1の出力はされるのですが、Class2の方はされません。 @質問 1.Class2にもイベントをレシーブするようにするにはどうしたらよいでしょうか。 2.上の実験では何が問題だったのでしょうか。 以上、お願いいたします。
>>90 とりあえずお前がやりたいであろうことをやってみた
結果、ちゃんと動く
問題はお前のコードにある
94 :
93 :2010/11/26(金) 04:17:19
検証コード 標準モジュール Public gMsg As Msg Sub main() Set gMsg = New Msg Set c1 = New Class1 Set c2 = New Class2 Call c1.a("Go!") End Sub MSGクラス Public Event Messege(ByRef str As String) Public Sub m(str As String) RaiseEvent Messege(str) End Sub Class1クラス Public WithEvents lMsg As Msg Private Sub Class_Initialize() Set lMsg = gMsg End Sub Private Sub lMsg_Messege(str As String) Debug.Print "Class1:" & str End Sub Sub a(str As String) Call lMsg.m(str) End Sub
95 :
93 :2010/11/26(金) 04:20:43
Class2クラス Public WithEvents lMsg As Msg Private Sub Class_Initialize() Set lMsg = gMsg End Sub Private Sub lMsg_Messege(str As String) Debug.Print "Class2:" & str End Sub まあ、グローバル変数にインスタンス保持して違うクラスで使いまわすのは 設計としてはあんまりよろしくないが、あくまで検証ということで あと、変数は作成じゃなくて宣言な つか俺眠れんからって何やってんだかw
96 :
90 :2010/11/26(金) 07:52:09
>>93-95 ありがとう。
出かける前なんでまだちゃんと読んでないけど、解読してみる。
OOPの考え方がよく分からないんで、インスタンスをどう保持すればいいか
正直よく分からないんだけれど、いろいろなクラスで使い回したい場合、
やっぱり引数でやりとりした方が良いんですか?
正直、OOPの考え方が分かるような本があれば読んでみたいと…
数を作ってれば体で覚えるよ。好きなものを作るといい。 最終的にオブジェクト指向にはそこまでこだわらんでもいいと気づく 超巨大なプロジェクトなら必須なんだろうかね、って程度
むしろ規模がでかい程体力重視で新人、素人ばっか
オブジェクト思考は共通機能にのみ適用って感じ
巨大な程に細分化してパーツ単位で作業するからな 指示不測のまま放り込まれた応援外注と新人がミス →そんな状態じゃ監督者も面倒見切れて無いから直前とか稼動後に発覚、がパターンw
101 :
デフォルトの名無しさん :2010/11/26(金) 11:36:23
excelにワークシート1と2を作りました。 ワークシート2にボタン1をおいてそのボタンをクリックすると、 ワークシート1から上半分だけを抜き出したリストを ワークシート2の上に作ろうと思います。 今現在ボタン1には何を記述すべきでしょうか。 検索してもまだ勉強2日目でいまいち要領を得ないので、 参考にできそうなサイトなどを教えてください。
>>101 別のシートに指定した範囲をコピーするのは、こんな感じで書けばいい
シートの名前とセルの範囲を書くと、右から左に内容がコピーされる
Worksheets("ワークシート2").Range("D11:F20") = Worksheets("ワークシート1").Range("A1:C10").Value
103 :
デフォルトの名無しさん :2010/11/26(金) 13:34:54
これでコピーはできました。ありがとうございます。 次は自分なりに勉強して特定の文字などの入っている行だけを抜き出して あたらしいふぁいるにするのに挑戦していきます。
104 :
デフォルトの名無しさん :2010/11/26(金) 18:26:02
セルをダブルクリックした場合に、セルを指定色で塗りつぶし、既に塗りつぶしてある場合は元に(塗りつぶし無し)戻す、というコードを書きたいです。 その際、A1をダブルクリックしたら赤、A2をしたら青…とA3、A4までの範囲で、それぞれ違う色を指定したいです。 ググってhitしたHPがありましたが、1色しか指定できませんでした。 そのコードのカラー指定部分を変更して2つ並べてみましたがエラーが出ます。 どなたかアドバイスお願いします。 ちなみに↓が参考にしたコードです。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Intersect(Target, Range("A1:A4")) Is Nothing Then Exit Sub With Selection.Interior If .ColorIndex = xlNone Then .ColorIndex = 4 Else .ColorIndex = xlNone End If End With Cancel = True End Sub
105 :
104 :2010/11/26(金) 18:27:05
書き忘れました。エクセルのバージョンは2003です。
select case
107 :
デフォルトの名無しさん :2010/11/26(金) 20:30:51
ググってるのですがちょっと分からないです…。 もう少し簡単に教えてもらえないでしょうか…。
108 :
デフォルトの名無しさん :2010/11/26(金) 20:39:42
109 :
デフォルトの名無しさん :2010/11/27(土) 13:57:29
VBAでエラトステネスのふるいってできる?
エラトステネスではないが素数をrange上限で指定した数に一番近い素数を求めるのなら Sub 素数サーチ() On Error GoTo Error num = Range("上限") Range("結果").Value = "Searching Now..." If num <= 1 Then GoTo 終わるよ num = num + 1 戻るよ: num = num - 1 If num = 2 Then GoTo two guusuu = num Mod 2 If guusuu = 0 Then GoTo 戻るよ For i = 3 To num / 2 Step 2 a = num Mod i If a = 0 Then GoTo 戻るよ Next Range("結果").Value = num Exit Sub
two: Range("結果").Value = 2 Exit Sub 終わるよ: Range("結果").Value = "素数なし" Exit Sub Error: Range("結果").Value = "error!" MsgBox "エラー内容:" & Err.Description End Sub もっと効率のいい方法あったら教えてくれ
>>109 できないわけがない
もちろん範囲によってはちょっと工夫が必要になるけど
検索と抽出についての質問なんですが シート1に入力 シート2にn列n行のデータの一覧とします。 シート1に入力した内容と一致するデータをシート2の該当部分から すべて抜き出してシート3にコピーするという作業を考えてるのですが Findで検索対象をさがして セル番地を取得して、その番地の行をコピーして シート3に貼り付け ってのをloopやforで繰り返す処理しか思い浮かばないのですが 上記のような作業を行う場合はこれでよいでしょうか? なんか変なやり方してる気がしますし findの使い方がいまいち理解しづらく頭がいたいです。。
set Rng = sheets("シート2").columns(1).find(FindStr) if not Rng is Nothing then Rng.EntireRow.copy sheets("シート3").cells(65536,1).end(xlup).offset(1) end if みたいに使う事が多いよ。 findで見つかった結果をRange型変数にsetして、検索結果が見つかっていたら処理をするって使い方が便利だと思う。 データの構造や持ち方がはっきり分からないからこれ以上は書けないけど、 ちょっと工夫してみれば出来ると思うよ。
大変参考になります。 サンプルまで書いていただきありがとうございます。 よく調べてみます。
長文失礼します。下記を前提としてBefore_Closeで処理がしたいのですが問題にブチ当たっています。 (1) マクロを仕込んだxlsファイル(仕込んでないものも)も同時に複数開かれる想定。 (2) キャンセルされた場合は処理をしない。(または処理前の状態に戻す必要がある。) ・Before_Closeが処理された後、未保存ブックの保存確認でキャンセルされると困る。 →キャンセルされた後に発生するイベントが無い!? →自前で保存確認して、 vbYesなら処理後に自前で保存してThisWorkbook.Saved=Trueにして本物の保存確認を回避、 vbNoなら処理後にThisWorkbook.Saved=Trueにして本物の保存確認を回避、 vbCancelならCancel=Trueで対応。 ・ブックを2つ開いて2つとも未保存のままExcelを終了しようとする場合、上記だと1つ目がvbNoで2つ目でvbCancelだと1つ目のSavedがTrueのままなので、再びExcelを終了しようとすると1つ目が保存確認せずに閉じられてしまう。 →うああああ結局キャンセル後に対処が必要じゃん! というところで手詰まりしています。苦肉の策として、 →Before_Closeで実装するのをやめてAuto_Closeに実装、 ※Auto_Close()であればマクロからCloseした場合にはイベント発生しないため。 vbYesなら処理後に自前で保存して自前で閉じる、 vbNoなら処理後に自前で閉じる、 vbCancelならApplication.ExecuteExcel4Macro "HALT(TRUE)"で対応、 としてとりあえず妥協しましたが、これだと1つ目で[はい]とした時点で1つ目が保存&閉じるので、2つ目で[キャンセル]しても1つ目がキャンセルされず通常の動きとは変わってしまう。。。 上手い解決方法はないでしょうか。Excelは2007〜です。
(2) キャンセルされた場合は処理をしない。 ってあるけどユーザーがマクロ実行後の結果を見て保存するかどうか決めるのかな? それならブックをコピーしてマクロで自動処理をさせて元ファイルと比較をした方が分かりやすいと思います。
>>117 いえ、保存せずに閉じようとした場合に表示される保存確認ダイアログですが、
表示されるのはBefore_CloseやAuto_Closeが終わった後なので、
[はい]か[いいえ]の場合だけ処理したい場合にキャンセルだと困るのです。
キャンセルの後で発生するイベントは存在しないようなので、
確実に[はい]か[いいえ]の場合だけ処理したいのであれば、
イベント処理の中で自前(MsgBox等)で保存確認ダイアログを表示するしかないようなのです。。。
クライアントの端末でファイルをコピーしたり削除するような処理は許可がおりません。
Excel上でWebbrowserコントロールを使って ページの上半分がグーグルマップ、下半分が表になるようにしてあります。 このシートを印刷をしたいのですが普通に印刷すると上半分が印刷されません。 下記の記述で上半分は印刷できるのですが今度は下が印刷されません。 Sub ボタン2_Click() ActiveSheet.Webbrowser1.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, 0, 0 ' 印刷 End Sub IEの領域は表にはかぶってないのですがどうすれば両方印刷できるのでしょうか?
Before_Closeは終了処理書けないしホント用途不明。 Before_Closeで他のブックも保存確認して処理しちゃうのはどう?
画像に取り込んでビットマップとして印刷したら?
>>113 の方の質問に似ているのですが
シート1にずらずら入力しているデータと
シート2にずらずら入力しているデータを比較して
マッチしているデータ行をシート1のマッチしたデータの下の行(既に数行空けてある)に
返す処理って可能でしょうか?
今まで手書きで処理していたため(前任)引き継いだ途端にテンパってます。
前任は音信不通…
泣きそうです
データ量とデータのある範囲とまっちさせる範囲と優先順位 A列だとするとこんな感じか? for i = 1 to シート1のデータ量マッチしてるならfor n=0tocells(i,1)のマッチ件数-1 シート3セル(m,)=マッチデータ m=m+1 マッチなし シート3セル(m,)=マッチデータ next next シート3をシート1に張り付け
>>121 CopyPictureではイメージの取得ができなかったのですが他に手はありますか?
125 :
デフォルトの名無しさん :2010/12/01(水) 07:58:03
>>124 SendKeysイベントでprintscreenキー操作すれば?
APIを利用して領域選択した後に加工したシートに張り付けかなあ 場合によってはスクロールして合成 シートの上webbrowserと他のオブジェクトがあるだけでそ なんで印刷出来ないのかね 手動印刷でも反映されないの?
mac板で質問したのですが、レスがつかないのでこちらに おじゃまします。 Excel2004で作成したプロシージャで、 ActiveWorkbook.SaveAs Filename:="(ファイル名)", _ FileFormat:=xlHtml, PublishOption:=xlSheet として複数枚あるシートのうちの一枚だけwebページ保存して いるんですが、2011で走らせるとブック丸ごと保存してしまいます。 仕様変更があったのかと思い、マクロの記録をしてみましたが、 正に上記のコードが出力されます。ちなみに、手動で保存をすると シート一枚をhtml出力させることができます。 参考書(2002用)を見てPublishObjects.Addなんかも試してみたんですが 意味がよくわからないうえに、うまく動きません。 誰か、たすけて。
>>127 Win 2010でマクロを記録してみた
With ActiveWorkbook.PublishObjects.Add(xlSourceSheet, _
"C:\Users\User\Documents\Book1.htm", "Sheet1", "", xlHtmlStatic, "Book1_26441" _
, "")
.Publish (True)
.AutoRepublish = False
End With
これでどう?
versionは2007の間違いね
>>128 ありがとうございまーーーーす!!
winではPublishObjects.Addで記録されるのですね。
まだ動いてません(438エラー)が、ものすごくヒントになりました。
もうすこし調べながらがんばってみます。
また、救助を求めるかもしれません。よろしくお願いします。
>>126 単純に、エクセルはブラウザ領域の描画を担当してないからでしょ?
質問させて下さい。 環境はwin XP(SP3),excel 2003です。 サイズが512×512の2次元配列C(a,b)をセ ルに貼付ける事を考えています。 ただし、Excel 2003では、列数が256なのでこのままで は不可能なので a=0 to 511, b=0 to 255をまず512行256列のセルに貼 付けて、 残りのa=0 to 511, b=256 to 511をその下の512行 256列(行番号513~1024)に貼付けようと考えています。 貼付け方は、処理を高速で行える様に Range(・・・)=C としたいのですが、貼付け先の並びが上述した様に不規則ですので 良い方法が浮かびません。 上手い方法を教えていただけないでしょうか。 宜しくお願いします。
>132 512×512の配列から512×256のふたつの配列にfor〜nextループ使って分けるしかないのでは?
134 :
132 :2010/12/02(木) 11:28:44
>>133 ご返信ありがとうございます。
やはりその方法しかないですか。
それでも、配列をfor 〜 nextループで直接書き込むよりは速いですよね。
ありがとうございました。
配列に格納するときに、257を越えてたら(+512,-256)にすりゃいいのでわ? 別ブックから持ってくるなら初めから配列2つ用意すりゃいいだけだし
>>132 前半256列はFor〜Nextで回さなくても
Range("A1").Resize(512, 256) = C
と書けば、配列の前半だけを一発でコピーできる。
後半もIndex関数を使えば1列分(512個)の要素が一気にコピーできるのでループは一重でいい。
>>134 ' 配列Cの前半0〜255列をコピー
Range("A1").Resize(512, 256) = C
' 後半256〜511列を257行目にコピー
For i = 1 To 256
Cells(513, i).Resize(512, 1) = Application.Index(C, 0, i + 256)
Next
excel2003 検索条件を入力させてシート内を検索させたいのですが 単一の条件での処理はうまくできましたが 複数条件の場合どのように記述すればよいのでしょうか? findの条件にANDを使ってもだめでした。
139 :
138 :2010/12/02(木) 23:56:32
説明不足でした。 条件A 条件Bを入力してもらい AかつBをシート内から検索したいと思ってます。 検索対象と条件はAはA列 BはB列のように列ごとにわけてあります。
>>138 A列検索してヒットしたら
B列検索してヒットしたらOKとすりゃいいだけ
エスパーするとAとBは同じ行じゃなきゃ駄目なんだろうから
Bの検索は(ヒットしたA列の行,B).valueで取得すりゃいい
142 :
デフォルトの名無しさん :2010/12/03(金) 15:41:11
Win XP、Excel2003(SP3)ですが、 初歩的な質問をさせてください。 Workbooks.Open Filename:="○○○.xls" Range("A1").Select Selection.Copy Windows("Book1.xls").Activate Range("B2").Select ActiveSheet.Paste End Sub これの ○○○ の部分に、 Book1のC3の値(文字列)を入力することはできませんか?
c3&".xls"
Dim strBookName As String strBookName = Workbooks("Book1.xls").ActiveSheet.Range("C3").Value Workbooks.Open Filename:="C:\pathname\" & strBookName & ".xls"
Sub test() With Workbooks("Book1.xls").Sheets("Sheet1") Workbooks.Open .Range("C3") & ".xls" ActiveWorkbook.Sheets("Sheet1").Range("A1").Copy .Range("B2") End With End Sub Book1がThisWorkbookと別フォルダーにある場合はPathを指定する また、シート名は明示するべき
仕事でエクセルに数字を入力したら、となりに計算された結果がでてきたから、関数でも入ってるのかとそのセルをみてみても、何も入ってないんだけど、そんなことVBAでできるん? valueじゃ普通入力されるよね
( ・`ω・´)
すまんw エクセル昨日の保護だったかw 普通にわすれてたwww
worksheet_chenge() ターゲットが数字なら計算してターゲットセルの右に出力
>>149 ごめんごめんw説明が悪かった
VBAで計算した結果を反映するのはできるけど、
結果の数字がセル内にみえなかったから、VBAでやってるのかとおもっただけw
全くわからん説明だ >結果の数字がセル内にみえなかった >となりに計算された結果がでてきた なんにしても意味わからん
セルの書式設定⇒保護⇒表示しない がかかってたんだろ エクセル機能を理解してればその説明でピンとくる
数式がセル内に見えなかったって書けばよかったんだろ? 結果は見えてるんだから。
計算した結果が出るはずのセルが空白であった。 にも関わらずそのセルを参照したセルに計算結果が表示されたって ことだと無理やり解釈した結果。 計算結果セルのフォントが白だったで一件落着
セル内にはいってなかったって書いてるんだから、数式バーぐらいみてるだろ
ユーザーフォーム上に2つのトグルボタンで 互いに片方が押されたら片方が飛び出るようにしたいのでそれぞれクリックイベントに (togglebutton1には) togglebutton1=True togglebutton2=False と (Togglebutton2には) togglebutton1=False togglebutton2=True を書き込んだのですが、思うように動きません。 オプションボタンを使わずに実現したいのですが どのようにすれば実現できるでしょうか?
Debug.Printして、どのイベントがどんな順番で何回実行され、 その前後でボタンの状態がどうなっているか確認しようか。 そういう話だと思うよ
結果的に実現できるでしょうか? クリック時とダブルクリック時で動作が違うのですが・・・。
>>157 何がやりたいのかよくわからん
常に逆の状態にしたいだけなら
Private Sub ToggleButton1_Click()
ToggleButton2 = Not ToggleButton1
End Sub
Private Sub ToggleButton2_Click()
ToggleButton1 = Not ToggleButton2
End Sub
たぶん、条件を後出ししてくると見た
出来るからこれをやって考えてみて。 理由が分かるはず。 Private Sub ToggleButton1_Click() Debug.Print "ボタン1クリック" & ToggleButton1.Value & ":" & ToggleButton2.Value ToggleButton1.Value = True Debug.Print "ボタン1をTrueにした" & ToggleButton1.Value & ":" & ToggleButton2.Value ToggleButton2.Value = False Debug.Print "ボタン2をFalseにした" & ToggleButton1.Value & ":" & ToggleButton2.Value End Sub Private Sub ToggleButton2_Click() Debug.Print "ボタン2クリック" & ToggleButton1.Value & ":" & ToggleButton2.Value ToggleButton1.Value = False Debug.Print "ボタン1をFalseにした" & ToggleButton1.Value & ":" & ToggleButton2.Value ToggleButton2.Value = True Debug.Print "ボタン2をTrueにした" & ToggleButton1.Value & ":" & ToggleButton2.Value End Sub
>>160 ありがとうございます。
そのままです。
実験的な意味合いが強いかも。。。
>>161 ありがとうございます。
試して考えて見ます。
分からなかったらまたくるかも・・・w
ワークブックに張りついている画像をすべてファイルに保存しようと思い、 以下のようにしてみたのですが、型が一致しません。といわれてしまいます。 どうすればよいでしょうか。 Sub test() Dim myPic As Picture Dim myWS As Worksheet Dim count As Integer For Each myWS In Worksheets myWS.Activate For Each myPic In myWS.Pictures SavePicture myPic, "test" & count & ".png" count = count + 1 Next Next End Sub
>>163 シートに直接張り付けてある画像はShapeオブジェクトになってしまうのでPicture関係のメソッドは使えない
画像をまとめて保存するには、ブック全体をHTML形式で保存するぐらいしか方法はないと思う
サブフォルダの中にオリジナルの画像データと、プロパティをいじって見た目を変えた後のデータが
それぞれ保存される
エクセルでシートが複数あります。 閲覧用のシートには項目a,b,c…と並んでいて データ保存用シートから 変数Xを取得したいのですが 閲覧用のシート 項目 変数 a Xa b Xb c Xc データ保存用シート 項目 a b c 変数Xa Xb Xc データ保存用シートは4つあり 項目は約1000個あります。 閲覧用シートの項目とデータ保存用シートの項目数は 一致しないこともあります。 閲覧用シートにある項目の変数を取得したいのですが どうすればよいでしょうか。
もしかして、4つあるシートのそれぞれ1000データから、閲覧と一致する項目があったら、データを抜き出して、閲覧シートに転写するってこと? それとも閲覧用シートにある項目の変数を取得したいってこと?
168 :
165 :2010/12/09(木) 08:05:37
>>166 前者です…。
VBAで一つ一つ検索することは出来るのですが…
一つ一つを繰り返せば?
一つ一つ総当たりで繰り返すんじゃなくWorksheetFunction.CouttIfで1以上かどうかで判定したら?
>>170 countifも総当たりだぞ?
ループの中でcountifなんて昨今のマシンじゃ配列の二重ループにも負けるくらいだ。
どっちもウンコだけど。
おまえらすごいな 質問者のやりたいことがどうにもよくわからん
エスパーじゃなきゃここでは勤まらないんだよ。
で、プログラマはまだか
171だが俺も実はやりたいこと分らんw
ただ
>>170 の考えが間違ってることだけはわかる。
find使うとかmatch使うとかいろいろあるが 簡単なのは3重ループかけて全件数処理 多少は次回かかるが
177 :
165 :2010/12/09(木) 16:22:32
3重ループですかorz 考えないようにしてましたが…
シートが少ないから2重ループ複数回でも データを別シートに書き出してからループでも VBA使わずに数式入れるでも
保存用シートが4つしかないんなら数式でINDEXとMATCHを4つ並べればいいじゃん
>>177 3重ループくらい普通にやれよ
パスワード解析でBFやる時なんて文字数分ループさせんだから
シート四つなら4重ループじゃないのか?w ここは馬鹿の一つ覚えでdictionaryだな。
183 :
165 :2010/12/09(木) 19:10:49
Dim s1 As Range, f1 As Range Dim a1 As Range, i As Integer Worksheets("list").Activate i = 3 For Each a1 In Range("S3", "S900") Set s1 = Worksheets("1").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else Set s1 = Worksheets("2").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else Set s1 = Worksheets("3").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else Set s1 = Worksheets("4").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else End If End If End If End If i = i + 1 Next
184 :
165 :2010/12/09(木) 19:11:49
できた。
インデントつけてみても意味が分らんけど、実質的に5重ループじゃね? Dim s1 As Range, f1 As Range Dim a1 As Range, i As Integer Worksheets("list").Activate i = 3 For Each a1 In Range("S3", "S900") Set s1 = Worksheets("1").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else Set s1 = Worksheets("2").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else Set s1 = Worksheets("3").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else Set s1 = Worksheets("4").Range("A1").CurrentRegion.Rows(1) Set f1 = s1.Find(what:=Cells(i, 1).Value) If Not f1 Is Nothing Then Cells(i, 19).Value = f1.Offset(1, 0).Value Else End If End If End If End If i = i + 1 Next
フラグを使って、見つかったらループ抜けるようにするといいんじゃね
For Eachが意味をなしてねーなw i = 3とi = i + 1は要らないだろ? Cells(i, 19)のところはa1だし。 Findも初期状態だと部分一致だがいいのか?
糞ソース読みが得意な俺様はやりたいことが分ったよ。
>>186 一応Findで抜けるようになってる。
質問です 特定のブックを開いたときに動作するマクロではなくて、 どのブックを開いたとき(エクセルを立ち上げたとき?)にでも動作するマクロってできるんですか?
>>189 アドインとクラス使えば出来るんじゃね?
Applicationレベルのイベントを捕まえればいいんだし。
workbook.openイベントじゃあなくて?
190だがクラスモジュール(クラス名は仮にClass1)に Public WithEvents Hage As Application Private Sub Hage_WorkbookOpen(ByVal Wb As Workbook) '処理例 MsgBox "禿げ" End Sub ThisWorkbookのOpenイベントで Private X As New Class1 Private Sub Workbook_Open() Set X.Hage = Application End Sub としてアドインとして保存。 後はこのアドインにチェックをつければブックが開くたびに"禿げ"と出る。
だ、だだだだだれがははははは!
>>185 はExcel2003以前ならたった898行のデータを、4シートのせいぜい多くても256列1行から探して
その下のデータを記入するだけだからFindでもいいが、多くなると毎回先頭の次から検索するから無駄もいいとこ。
3重ループを考えないようにしてると言ってるのに実質5重ループやってる。
>>189 余計なシートが開いちゃうけどXLSTARTにWorkbook_Openが一番簡単かな
まあ自力でやったんだからいいじゃないか 俺なら作業シートに5シート分の全データをコピーして 検索の数式入れて結果を元のシートに値貼り付けとかやってみるかな コードは確実に短くなると思うけど、スピードはVBAでループするのとどっちが速いかな
おそらく数式使うほうが早いんじゃないかね
>>195 1回だけなのか?
俺は複数のブックを開いて実行するマクロだと思ったが?
>>197-198 数式使うにしても単純な検索関数じゃ速くならん。
速く計算するならソートは必須。
VBAなら素人の定番dictionaryが簡単かねぇ。
>>165 えーと、複数シートから検索するのって
VBAなんか使わなくてもこれだけでいいと思うんだけど…
T3=IFERROR(INDEX('1'!$2:$2,1,MATCH(S3,'1'!$1:$1,0)),"")&IFERROR(INDEX('2'!$2:$2,1,MATCH(S3,'2'!$1:$1,0)),"")&IFERROR(INDEX('3'!$2:$2,1,MATCH(S3,'3'!$1:$1,0)),"")&IFERROR(INDEX('4'!$2:$2,1,MATCH(S3,'4'!$1:$1,0)),"")
そんな糞式VBAスレでさらすな。
誤爆にレス データが1000個横に並んでるって書いてるから2003以前はありえない
なるほど1000列かよ。1000が898になったと勘違いしてたわ。 だったら2007以降だな。
250個x4シートだと思ってた
206 :
165 :2010/12/10(金) 08:30:31
もっと褒めてほしい。
250×4が横に並んで
縦に1000という感じ。
エクセル2003です。
>>187 For Eachとiは共存しなくてもできるのか。。
Findの初期状態が部分一致なの始めて知った、けどOK。
本見ながら試行錯誤したんだよね。
>>199 dictionary最初に教えてくれ(;;)
>>196-197 一応書いたのはデータを一個取ってくるだけだけど
最終的には一つの項目に対して
複数のデータを取りたいので
そういう形にはしたくなかったのです。
>>206 自分で考えたんなら褒めてやらんでもないが基本がまったくできてない。
CurrentRegion.Rows(1)とか書けるのに何でだ?
お前ネタで変なコード書いたんじゃないのか?
ネタに混じれ酢かも知らんが、Cells(i,1).Valueすなわちa1.Offset(,-18).Valueを最高4回も取得してるが
何度も使うものは変数に入れて使いまわさないと。
またFor EachもA列のデータ範囲を回すのが普通だと思うが、まぁこれはおいといて
If Not f1 Is Nothing Then
Cells(i, 19).Value = f1.Offset(1, 0).Value
Else
すなわち
If Not f1 Is Nothing Then
a1.Value = f1.Offset(1).Value
Else
も4回も書く必要ナス。
1回でいい筈だ。
dictionaryに手をつけるにははまだ早いねぇ。
最初は誰だってこんなもんだよ 局所的に必要な処理を順に積み上げていくと冗長なコードになる 全体を見渡して効率のいいコードが書けるようになるには訓練が必要だからね とりあえず、データを4つのシートに分けた理由が「幅が足りない」だったら データは縦に並べて1枚にまとめた方がいい、とだけ言っておこう
俺は幅が足りても縦に並べるべきだと思うな。 下へ下へと伸ばしていくのがExcelの流儀だからな。
VBAつかうんだったらわざわざシートに乗せる必要もないしな テキストなりに格納して必要な所だけ抜き出せばいい
211 :
デフォルトの名無しさん :2010/12/10(金) 23:58:02
| A | B | C | C|五月|金額|累計| D|六月|\200|\200| E|七月|\300|\500| F|八月|\400|\900| C列にあるような累計を出すプロシージャを作りましたが、うまく機能しません。 どなたか、下記の間違いを指摘していただけませんか? Sub 累計() Dim i As Long i=5 Do While Cells(i,2).Value<>"" Cells(i,3).Value=Cells(i,3).Value+Cells(i,2).Value i=i+1 Loop End Sub
>>211 5月のところにまともなデータが入ってないけどそれでいいの?
Sub 累計()
Dim i As Long
Cells(5, 3).Value = Cells(5, 2).Value
i = 6
Do While Cells(i, 2).Value <> ""
Cells(i, 3).Value = Cells(i - 1, 3).Value + Cells(i, 2).Value
i = i + 1
Loop
End Sub
213 :
デフォルトの名無しさん :2010/12/11(土) 00:25:44
>>212 ありがとうございます。
『五月』ではなく、項目名の『日付』でした
セルズプロパティではなく、アクティブセルプロパティを使って書くのはできたのですが、
こうしてみるとセルズプロパティーだと長くなってしまうんですね
214 :
デフォルトの名無しさん :2010/12/11(土) 01:39:34
アクティブセルプロパティを使って書くと、
Sub 累計()
Dim total as long
Range("B5").Select
Do While Activecell.Value<>""
total=total+Activecell.Value
Activecell.Offset(0,1).Value=total
Activecell.Offset(1,0).Select
Loop
End Sub
こうなりますが、
>>211 のDo Whileのステートメントの下の
Cells(i,3).Value=Cells(i,3).Value+Cells(i,2).Value
なぜ、これは駄目なんでしょうか?
今書いたアクティブセルプロパティでは、
total=total+Activecell.Value
でオーケーなので。
ここが特に理解に苦しみます。
>>214 totalは1つしかないけど
Cells(i, 3)はiの数だけあって常に0だから
ちなみにプログラムを短くしたいならこういう方法もある
Sub 累計()
Dim c As Range
Cells(5, 3) = Cells(5, 2)
For Each c In Range(Cells(6, 2), Cells(Rows.Count, 2).End(xlUp))
c.Offset(0, 1) = c + c.Offset(-1, 1)
Next
End Sub
質問なんですが、シート上にある無作為にあるオブジェクト(オートシェイプや画像など)をすべて抽出する方法ってありますか?
>>216 オブジェクトって色々あるけど、オートシェイプと画像だけなら
For Each s In ActiveSheet.Shapes
218 :
デフォルトの名無しさん :2010/12/11(土) 10:34:42
Vista Excel 2007 質問させていただきます。 Dドライブに、2つのファイルiiyo.xlsxおよびkakuyo.xlsmを作りました。 kakuyo.xlsmの標準モジュールには、次のマクロ(kakuyo)を記述しました。 Sub kakuyo() Workbooks.Open Filename:="D:\iiyo" Cells(1, 1) = 123 End Sub また、マクロkakuyoには、Ctrl+Shift+vのショートカットを割り当てました。 このとき、マクロダイアログボックスの一覧から選択してマクロkakuyoを実行すると、iiyo.xlsxのA1セルに数値123が書きこまれます。ところが、同じことをショートカットで実行しようとしても、iiyo.xlsmを開くところまではいいのですが、数値123を書き込むことができません。 なぜ、ショートカットでは最後まで実行できないのでしょうか。また、ショートカットで最後まで実行するにはどうすればよいのでしょうか。
>>218 それじゃどこのCells(1,1)か分からないだろ?
どこのブックのどこのシートのCells(1,1)か明示したら?
質問です セルからすこしはみ出たオートシェイプをきちんとセル内の上に置く方法ってありますか? ピクセル計算とかして割り出すしかないですか?
>>221 いちいち計算しなくてもこんな感じでできる
Sub 図形をセルにピッタリおさめる()
Set cell = Range("B2")
With ActiveSheet.Shapes(0)
.Top = cell.Top
.Left = cell.Left
.Width = cell.Width
.Height = cell.Height
End With
End Sub
XP Excel 2003 シートにあるグラフ内をマウスでクリックしたとき、グラフの左下を原点(0,0)として 左上が(0,1)、右上が(1,1)、右下が(1,0)となるように正規化したクリック位置が得られるような VBAマクロを作ろうとしていますが、うまく正規化できず困っています。 現状は ThisWorkbook 内で Private WithEvents evchart As Chart Private Sub Workbook_Open() If evchart Is Nothing Then Set evchart = Worksheets("シート名").ChartObjects("グラフ名").Chart End If End Sub を準備した上で Private Sub evchart_MouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long) の中で、x,y の座標値と Worksheets("シート名").ChartObjects("グラフ名").Chart.PlotArea.InsideLeft などのポイント値を 対応付けようとしていますが、座標値←→ポイント値の換算を考慮しても、グラフサイズを変えたときでも正規化がうまくいくような 記述に持ち込めません・・・ クリックイベントx,yをこう処理すれば冒頭の正規化がなされた値にできる、ということが分かる方が居ましたら教えてくださいm(_ _)m
>グラフの左下を原点(0,0)として これは「グラフのXY軸が左下で交わる点を原点(0,0)として…」とする方がより正しいですね。
225 :
デフォルトの名無しさん :2010/12/11(土) 11:55:05
>>220 早速ありがとう。
Sub kakuyo()
Dim iiyo As Workbook
Set iiyo = Workbooks.Open("D:\iiyo")
iiyo.Sheets(1).Cells(1, 1) = 123
End Sub
こうしても同じ(つまりショートカットではファイルを開くところまでしか実行しない)だったよ。
>>218 別のショートカットキーを割り当ててもダメ?
なんか2007のバグっぽい気もするけどキーが他で使われるとか?
どうしてもショートカットキーでやりたいなら別の手段があるけど
>>223 ここはVBAスレなのでVBの話題はスレチ
228 :
デフォルトの名無しさん :2010/12/11(土) 12:26:02
>>226 他のショートカットも試してみました。
すると、Ctrl+vのようなShiftなしのショートカットなら最後まで実行し、Ctrl+Shift+vのようにShiftを使うと、ファイルを開くところまで終わりました。
Shiftを使わないショートカットでは、すでに多くの機能が割り当てられているため、隣のキーを押したりして操作ミスの可能性も高まります。できればShiftを使いたいので、別の手段をご教示ください。
ウインドウ枠の固定をマクロ記録してみたら
できました ありがとうございます この機能を知りませんでした・・・
>>228 もしかして、Shiftを押しながらブックを開くとマクロが無効になる機能が誤作動してんのかな?
だとしたらShiftを押さない方法を考えた方がいいかも
excel2007 月日を2桁で表示させたくてコード書いたら何故か MsgBox CStr(Year(Now()) & "-" & Format(Month(Now()), "mm") & "-" & Format(Day(Now()), "dd")) 2010-01-11 と表示されてしまってるんですけど、どうして????? システム日付は当たり前のことながら 2010-12-12になってるんですけど Cstrで文字列に変換しているのはこの後の処理で文字列として使うのがあるからなんですけど
MsgBox CStr(Format(Now(), "yyyy") & "-" & Format(Now(), "mm") & "-" & Format(Now(), "dd"))
238 :
236 :2010/12/12(日) 20:59:42
余計なことしすぎみたいな? w ありがとう
>>236 すでに回答が出てるが、Format(Month(Now()), "mm")の部分はシリアル値12、すなわち1900/1/11の月を
求めているから当然01となる。
Format(Day(Now()), "dd")も1900/1/11の日だから11.。
そもそもなんでそんな面倒なことするの?
下で都合が悪いのか?
MsgBox Format(Now, "yyyy-mm-dd")
Cstrが入ってるから MsgBox Format$(Now, "yyyy-mm-dd") だったわ
241 :
デフォルトの名無しさん :2010/12/12(日) 21:21:47
242 :
デフォルトの名無しさん :2010/12/12(日) 22:00:22
>>235 おっしゃるとおり「Shiftを押しながらブックを開くとマクロが無効になる機能」が関係していそうですね。
この機能のことは知りませんでした。ありがとうございます。
無効になるなら、最初から動かないんでないかい?
244 :
243 :2010/12/12(日) 22:19:29
わるかった。バグとしてはあり得る。
新しく開くブックをマクロ無効で開くってことだろ
検証すんのが面倒だからアイデアだけ マクロの先頭で数秒間スリープして、その間にキーを離せば 誤作動かどうか確認できるんじゃない?
マクロを有効にして開くオプション付けてもシフト有線されんのかね
248 :
226 :2010/12/13(月) 08:05:23
>>228 shiftをどうしても使いたいんだよな?
winショートカットキーでマクロファイル指定すりゃいい
for each x in range("a1:a5") next msgbox x is nothing ってするとエラーになります。 なんで? ループが終わればnothingになると思いましたが...
True
>>249 Option Explicitくらい書けよ。
変数宣言してないに1兆円だな。
Variant型だったらループを回りきればEmptyだからx Is Nothingじゃエラーになるわな。
オブジェクト型ならエラーにはならん筈だ。
もちろんこの場合はRange型な。
アドバイス願います。 xl2010でシートにファイルから写真を挿入 (○)手動でサイズ変更 > ブック保存 保存したブックを開く> 原形サイズは(1)の時点と同じ これは意図したとおりでOK. (×)上記(1)に対象にして以下を実行後、ブック保存 Selection.ShapeRange.ScaleHeight 0.5, msoTrue 再度開くと、(1)の時点の原形サイズが 保存時の50%縮小のサイズになっている 当然ながら図の書式ダイアログのサイズの拡大縮小ボックスも 100%になっている VBAでやるとなぜ原形サイズを保持できないか 理由がわかる方、ヒントでもいいのでアドバイス願います。
選択した画像を50%にするコードに読める。 よってそのコード通りの処理がされているだけなのでVBAは何も悪くない。
質問です。 二次元配列を縦横入れ替えるとき、WorksheetFunction.Transposeと自前ではどちらが速いですか?
>>255 自分で計ってみれば分るだろ?
もっともまともに公平に比較計測できる人少ないけどな。
>>256 そのとおりですね。
自分では何度やっても自前が速いけど、人によってはTransposeが速いという人もいるので環境によって違うのかとおもって。
>>257 俺はTransposeは遅いが常識だと思ってたがそんな人いるのか?
そもそも速い遅い以前にi色々問題があって使いたくないけどな。
ちなみに今10*40000のString型配列(6〜9文字のランダムなアルファベット)でやってみたが、5回平均で
自前: 595ミリ秒
Transpose:: 992ミリ秒
だったぜ。4割自前が速いな。
変換後は自前はString型、Transposeは仕様によりVariant型だ。
セルへの書き出しは時間に入れてない。
環境は
Excel2007
メモリ:4GB
CPU: Core2Duo E8500
OS:Vista 32ビット
そんなに急いでどこへ行きたいんだ?
そう、速さより確実性だ。 速さも確実性も備わってりゃ言うこと無し。 その点WorksheetFunction.Transposeは不合格ってこったな。 Excl2003なら使えなくもないかな? 昔の2000とかでは配列ではしょぼすぎて使えない。
差が1秒イカならコードがすっきりする方を選ぶでゲソ
>>261 同意。それが結局トータルでは速くなったりするわな。
自前の変換の関数くらい誰でも持ってるんじゃね? WorksheetFunction.Transpose使うやつは俺が知ってる限り下手くそばっか。 WorksheetFunction.Transposeってより何故かApplication.Transposeだが。
セルをクリックしたらオートフィルターかかようにしたら、 かかったり、解除されたりしてデバッグになる>< 一応、フィルターモードを確認してるんだけど、なんで解除されたりするんだ・・・
WorksheetFunction.Transposeねぇ。 これってどっちかの次元が65536超えたらアウトだろ? 俺もまず使わない。 エラーにはまずならない2003の頃でも使わなかった。 理由はVariant型で遅いから。
>>264 フィルターモードの確認なんて必要ないだろ?
With Range("A1").CurrentRegion
.AutoFilter Field:=1, Criteria1:="***"
End With
なんて書けば絶対にフィルターモードにならないか?
>>266 まじか・・・
それかいてるんだけど、はずれたりするんだよね。
そのまえの
heets("Sheet1").Rows("1:1").AutoFilter
が余計かな
>>267 そんなもの書いちゃいかんよ。
例えばこんなのは無意味だ。
With Range("A1").CurrentRegion
If Not .Worksheet.FilterMode Then
.AutoFilter
.AutoFilter Field:=1, Criteria1:="a"
'処理
.AutoFilter
End If
End With
最初からこう書けば良い。
With Range("A1").CurrentRegion
.AutoFilter Field:=1, Criteria1:="a"
'処理
.AutoFilter
End With
間違った。こんなのが無意味ってことね。 With Range("A1").CurrentRegion If Not .Worksheet.FilterMode Then ’無意味 .AutoFilter '無意味 End If '無意味 .AutoFilter Field:=1, Criteria1:="a" '処理 .AutoFilter End With
>>270 If Not .Parent.FilterMode Then .AutoFilterの部分か?
If .Parent.FilterMode Then .AutoFilterでも最終的な動作は同じだろ?
無駄だと思うなぁ。
しかし.Parentかよ。
OS:XP Excel:2003 超初心者ですが質問させてください。 現在、YahooID自動取得プログラムなるものを作ってます。 (三流氏のソースを引用してます) IEを使ったものだとうまくいったのですが、 Firefoxだとうまくいきません…。 自動入力の対象がFirefoxの場合は、このようなことは無理なのでしょうか? できるとしたら、どのようにやればよろしいのでしょうか…orz
273 :
272 :2010/12/14(火) 11:05:23
274 :
272 :2010/12/14(火) 11:09:40
プログラム上のFor文の中でIEを探して、objIEに起動中のIEをセットしてるので、 For文をなくして、起動中のFirefoxのウインドウを入れてみても、うまくいきませんでしたorz 具体的には、For文の処理をコメントアウトして、下記を追加しました。 Set objIE = objShell.Windows(0) わかるかたがいらっしゃいましたら、ご教授の程、宜しくお願い致します。
275 :
255 :2010/12/14(火) 11:16:43
いろんな意見どうもです。
Transposeが速いって方、ここではいませんね。
あそこで聞いてみるかなぁ。
>>258 それって縦横変換部分だけの時間ですか?
例えば
t = timer
v = worsheetfunction.transpose(配列)
debug.Print timer - t
みたいな。
>>275 そうか、俺は毎回10*40000のランダムな文字列作ってたわ。
Rnd(-1)としてるから毎回同じだけどな。
上の計測はその作成部分も入ってる。
縦横変換された配列作る処理だけ計ったら109ミリ秒と178ミリ秒だった。
サイズ間違えたわ。 10*40000なら399ミリ秒と644ミリ秒な。
278 :
255 :2010/12/14(火) 13:34:46
>>276-277 了解です。
うちとはCPUとOSが違いますが、だいたい似たような傾向です。
質問なんですが、 Worksheet Change イベントで、 Application.ScreenUpdating = False をつかうと、画面が固まるの仕様? ちなみにエクセル2000と2003です
>>274 ソース見てないけど
FFのプロセスIDやウィンドウ名を取得すればできる
残念ながらWScript.Shellなのでスレ違いなんだぜ
上のヒントを参考に頑張れ
意外と直ぐに出来ると思う
質問!! だれかしってたらおしえて!! シートの保護つかわないで、オートシェイプをうごかせないようにする方法ない??
>>281 オートシェイプの固定はシートの保護を使わないと無理
データを入力できるようにしたいんなら、逆にそのセルのロックを解除しとけば保護されなくなる
284 :
デフォルトの名無しさん :2010/12/15(水) 03:24:19
Excel2007です。 ワークシート上に直接、 ・フォームコントロールのコンボボックス ・ActiveXコントロールのコンボボックス がそれぞれ一つずつ、計二つ配置されているとします。 これらに設定されているテキストを取得したいのですが、 後者は、 MsgBox ActiveSheet.ComboBox1.Text で取得できます。 では、前者の方は取得できますでしょうか。 フォームコントロールをActiveXコントロールに変更できない 事情がありまして、 フォームコントロールのコンボボックスの値をどうしても取得したいのです。 よろしくお願いします。
データをシートにロードする場合に、その過程がユーザーに見えちゃったらカッコ悪いでしょ 見た目的に そのために画面描画を停止させる事が出来るんだよ falseにしたら何が起きようとも必ずtrueに戻してね
>>280 アドバイスありがとうございます。
単語の意味すら全くわからんけど、なんとか頑張ってみますw
Excel2007 ワークシートに貼りつけたボタンでシートのクリアをしているんですけど(見出し部分は除く)、 ワークシートを移った時に自動的にしようと思い、以下のコードをワークシートモジュールに書いたんですけど、 RangeクラスのSelectメソッドがしっぱいしました って実行時エラーになってしまいます。 Private Sub Worksheet_Deactivate() Dim tate As Long Cells(1, 2).Clear Range("a10000").End(xlUp).Offset(1).Select ←ここでエラー tate = Selection.Row If tate >= 3 Then Range(Cells(3, 1), Cells(tate, 7)).Clear End If End Sub どうすればいいですかね
>>289 シートをDeactivateしたらそのシートのセルはセレクト出来ないのは当然。
アクティブになったシートなら
Activesheet.Range("a10000").End(xlUp).Offset(1).Select
としないと動かん。
その前のCells(1, 2).Clearもお前の考えてるシートのセルじゃないと思う。
291 :
mai :2010/12/15(水) 13:11:09
はじめまして、質問です。 EXCEL2003で、次のようなマクロをシート上のコマンドボタンに登録して使っておりました。 「通常使用するプリンター」以外で毎回そのシートを印刷したかったときです。 Application.ActivePrinter = "EPSON PM-3300C ESC/P R on Ne08:" ActiveWindow.SelectedSheets.PrintOut From:=1, To:=1, Copies:=1, _ ActivePrinter:="EPSON PM-3300C ESC/P R on Ne07:", Collate:=True このたび会社のPCが変わりまして、EXCEL2010になったのですが、このマクロがエラーになります。 ESC/P R on Ne08 の、08を01〜09に変えて試しましたが、変わりませんでした。 ためしに、マクロの記録で同じ動作を記録してみましたが、「何もなかったこと」にされています。 EXCEL2010では activeprinter 自体が認識されないのでしょうか???
292 :
mai :2010/12/15(水) 13:26:16
すみません、わかりました。 activeprinter の問題ではなく、ただ単にプリンターの指定が間違っていました。 お邪魔しました。
>>290 >シートをDeactivateしたらそのシートのセルはセレクト出来ないのは当然。
あっ確かに w
けどそうすると、ワークシートが変わったときにって判断は無理?
>>289 Private Sub Worksheet_Deactivate()
Dim tate As Long
Cells(1, 2).Clear
tate = Cells(Rows.Count, "A").End(xlUp).Row
If tate >= 3 Then Range(Cells(3, 1), Cells(tate, 7)).Clear
End Sub
Rangeオブジェクトにはシート名を付加した方がいいが、
今回の場合は、あえて付加しなくても可。
また、Selectは必要最小限にした方がベター。
>>294 添削ありがと!
勉強しなおしてきます!
テキストボックスで半角カナを強制したいと思い、プロパティで[fmIMEModeKatakanaHalf]を指定しました。 マクロは動いたのですが、その後ワークシートに戻ってキーボードで日本語入力をONすると半角カナになってしまいます。 いちいち入力モードを変更したくないのですが、マクロ内でIMEモードをリセットする方法はありませんか? リセットと言うか、次回日本語入力にしたときに全角ひらがなモードにならないでしょうか?
テキストからフォーカスが外れた時にIME変更汁
>>297 Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
TextBox1.IMEMode = fmIMEModeHiragana
End Sub
↑付けたら希望通りになりました。ありがとうございました。
これで正解でしょうか?(とりあえず動けばOKの精神なので細かい事は分かりません)
他にいい記述があったら教えて下さい。
299 :
130 :2010/12/16(木) 10:37:47
その節はありがとうございました。 その後、教えてもらったコードも438エラーを 解決できず、これはバグに違いないだろうとMSのサポートに TELしたのですが、VBAのサポートは内容により有償になると 言われました。(3万8千だって) 不具合報告があるかどうか確認したかっただけなのに… びびって有償サポートにはTELできませんでした。 仕方がなく、一旦別のブックにコピーしてからWeb用に保存する なんともスマートじゃない方法で凌いでいます。 MSって…
300 :
デフォルトの名無しさん :2010/12/16(木) 12:04:49
このスレに質問するレベルで「MSのバグ」というのは100年早いレベル
301 :
128 :2010/12/16(木) 17:15:43
>>299 Excel2011、試してみた
最初に言っておくとMacは初心者なのでミスはあるかもしれない
しかし、マクロの記録時にはシートのみで保存が出来たにもかかわらず
同じマクロを(先に保存されたHTMLファイルはリネーム済み)走らすと
確かにBookでしか保存されない
PublishOptionが正しく反映していない気がする
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target = Range("C3:T20") Then If Target.Value = "" Then Target.Value = "壁" Else Target.Value = "" End If End If End Sub C3:T20のいずれかをダブルクリックしたときの動作のことなのですが C3:T20ではエラーがでてしまうのでC3,C4・・・T19,T20と一つ一つ書かないとダメなのでしょうか
>>302 Intersectを使って
If Not Intersect(Target, Range("C3:T20")) Is Nothing Then
できました!ありがとうございます
305 :
デフォルトの名無しさん :2010/12/16(木) 18:43:14
すみません":="の意味を教えていただけないでしょうか。 通常の"="と違いがあるのでしょうか。 ググっても全く出て来ず、発狂しそうです。 よろしくおねがいします。
If MsgBox("ほげ", vbYesNo) = vbYes Then If MsgBox(prompt:="ほげ", Buttons:=vbYesNo) = vbYes Then
>305 「+VBA 名前付き引数」でぐぐる。
308 :
305 :2010/12/16(木) 19:09:32
ありがとうございます。 キーワード引数を使う場合は:=を使わなければならない、という仕様ということですか。 ほんとVBAは意味不明な仕様だらけで心底爆発して欲しいです…orz
自分がそれに慣れていないだけの話やんけ、ヴォケ
名前付き引数というか名前付きパラメータ自体は、 他の言語でも一寸したトリックっぽい書き方で使われてたりするから、 VBAが特別という程の話でもない。
311 :
305 :2010/12/16(木) 19:53:07
普通は=だと思うんですけどねえ…。Pythonとか。 引数の与え方で()省略があるとか、オブジェクトの代入はsetだとか、無駄に冗長な仕様が多くて嫌いです。
Pythonの代入演算子=は値を返さないからな。 VBAだと比較演算子になるし、他言語でも値を返すことが多いから、 明確に意味合いを変えられるPythonの方が珍しいかと。 ()省略強制とかSetとか鬱陶しいのは同意。
迷路探査AIで詰んだ
314 :
299 :2010/12/16(木) 22:49:58
>>301 重ね各々ありがとうございます。
やっぱり僕だけじゃなく、不具合なんですよね。
MSに知らせた方がいいと思うんですが、思い切って
有償窓口にTELしちゃってもいいですかね?
>>300 重々承知していますが、win95以降くらいからMSが
ダイッ嫌いなんです。
できればOfficeもOpen Officeに切り替えたいんですが…
あとは、察して下さい。
sortに失敗したとエラーで止まって、再開するとVBAが無限ループにおちいることがあるな
316 :
デフォルトの名無しさん :2010/12/16(木) 23:40:51
下記のソースコードに、 16進数の文字列"8FFFFFFF"を負のバイナリ値(-1879048193)に変換するアルゴリズム書ける人いますか? 16進数の文字列"7FFFFFFF"を正のバイナリ値(2147483647)に変換する処理はできたんですが… Public Const DATALEN_MAX As Long = (8) Sub Macro1() Dim sInput As String Dim bCode() As Byte Dim lResult As Variant Dim lDigit As Variant Dim iLen As Integer Dim i As Integer
317 :
316 :2010/12/16(木) 23:42:50
On Error GoTo Error sInput = "8FFFFFFF" '変換後期待値=(-1879048193) 'sInput = "7FFFFFFF" '変換後期待値=(2147483647) '最大で8桁(4byte)の入力まで受け付ける iLen = Len(sInput) ReDim bCode(iLen - 1) As Byte '文字列を1桁ごとにバイナリ変換してByte配列に格納する '例. "ABCD"なら、bCode[0x0A][0x0B][0x0C][0x0D] i = 0 Do While i < iLen '16進数以外の文字が入力されるとここでエラーとなる bCode(i) = "&H" & Mid(sInput, i + 1, 1) i = i + 1 Loop
318 :
316 :2010/12/16(木) 23:43:35
'各バイトの値を桁数に対応した数値に変換して、 '変換後の各桁の値を加算した結果が求めるバイナリ値 'D + (C * 16) + (B * 16の2乗) + (C * 16の3乗) i = 0 lDigit = 1 If bCode(0) < 8 Then '正の値 Do While (i < iLen) And (i < DATALEN_MAX) lResult = lResult + (bCode(iLen - i - 1) * lDigit) lDigit = lDigit * 16 i = i + 1 Loop Else '負の値 '★ここにどんな処理を実装すれば '★負のバイナリ値を算出できるのかわかりません End If Debug.Print lResult Exit Sub Error: Debug.Print "abnormal input" End Sub
Val("&H" & Hex)
320 :
316 :2010/12/16(木) 23:49:46
>>319 できました!
自分で関数作った私がバカでした…。
-1してビット反転で絶対値を取って符号を付けて完了、 ってのを自前でやれって宿題か?
VBAでバイナリ処理とかしたことないけど、でも出来るんだよな EXCELメモリエディタ作れたら読み出しが楽かも
323 :
316 :2010/12/16(木) 23:54:56
えー
宿題ならむしろ
>>319 つかっちゃだめだろw
325 :
316 :2010/12/16(木) 23:59:20
あ、いや宿題ぢゃなくて、ツール作りたいだけ
326 :
128 :2010/12/17(金) 00:29:17
>>314 前は、 MSDN インシデントを使って、いくつか報告した事あるけど、
十中八九、報告しなくても修正されると思いますよ
(報告したところで、致命的でなければ他の修正とまとめてリリースでしょうし)
Macは詳しくないけれど、2008でVBAマクロ機能が除去されて
2011で復活したばかりのようなので、他にも色々ありそうな気はします^^;
IS演算子の振る舞いについて。 セルA2をアクティブにしたらという処理で 通常はこんなことはしないが、試に、 IS演算子を使ってみたところ、A2クリックで反応なし Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target Is Range("A2") Then MsgBox "A2" End If End Sub で、以下を試したところ Sub Test() Dim A As Range, B As Range, C As Range Set A = Range("A2") Set B = Range("A2") Set C = A MsgBox "AisB= " & (A Is B) & vbLf _ & "AisC= " & (A Is C) End Sub 結果は AisB=False、AisC=True なぜこうなるか理由がわからん、情報求む!
on error でエラーを無視&エラーログをとる方法ってありますか?
マクロを有効選択で開き、途中ボタンクリックで無効にする方法ってありますでしょうか?
330 :
デフォルトの名無しさん :2010/12/17(金) 23:30:00
>>328 ある
resumeしてlog吐いて終了
331 :
デフォルトの名無しさん :2010/12/17(金) 23:32:09
>>329 ある
途中が何の途中なのか分からんがExcel中でもマクロ実行中でも出来る
332 :
デフォルトの名無しさん :2010/12/18(土) 00:50:58
333 :
314 :2010/12/18(土) 01:32:06
>>326 >他にも色々ありそうな気はします
不安です…
2008。買ったんですけど、買った後にVBA非搭載を知り
返品しました。
ソフトを返品するって、初めてでした。道義的にありえない
行為ですから。
でも、販売店には悪い事したけど返品しました。
VBAが使えないなら、OpenOfficeで充分ですからね。
ハイブリッド車がほしくてプリウスを買ったら、
実はただのガソリン車だったとしたら…
と例えたら、販売店は納得してくれました。
334 :
316 :2010/12/18(土) 01:42:15
16進文字列⇒バイナリ値変換の話、
0x80000000を負の値として扱う場合は
>>319 が適当だが、
これをUnsignedの正の値に変換したい場合は
>>319 じゃ無理な気がしてきた。
0x80000000をUnsignedのバイナリ値に変換したい場合、
>>316 のような自作関数を使うしかないんじゃないの。これ。
335 :
128 :2010/12/18(土) 01:51:41
>>333 不安にさせたのは申し訳ない
意外にすぐパッチ当たる気も、同時にしてしますけどね
これに限らず最新版は必ずしも安定しているわけでないので
古いバージョンをあえて使うのも一つの見識かとは思いますよ
337 :
327 :2010/12/18(土) 16:10:00
>>332 情報感謝!
提示のサイトに書いてあるように
別オブジェクトと考えればそのような結果にはなるが、
なぜ、Range("A1")とRange("A1")を別オブジェクトと
見なさないといけないのか(見なしているのか)は、ん?状態。
Sheet、WorkbookはTRUEということを考えると
Rangeオブジェクトは特異な存在ということに。。
そんなもんだと思えばそれでいいが、ちょとすっきりしないので
ここは閉めて、別なところでも質問投げてみたいと思ふ。
何れにしろ、迅速な情報感謝。ありがとう。
338 :
デフォルトの名無しさん :2010/12/18(土) 16:55:11
教えてください。 以下のコードでファイルをオープンしてwb変数にいれた後、 ForEachで現在開いているブック全部見てtmpWbに入れますが、 直前にオープンしたはずのwbが取得できません。 取得するにはどうすればいいでしょうか? CreateObjectを使ってるからいけないのでしょうか? 都合があって参照したブックを裏で開きたいのです。 普通に開くとブックが見えてしまう。 開いた後にWindows.visibleをFlaseに設定しても 開いてるところが一瞬チラッと見えてそして隠れてしまいます。 Dim objXls As Object Dim wb As Workbook Dim tmpWb As Workbook Set objXls = CreateObject("Excel.Application") Set wb = objXls.Workbooks.Open(ファイル名) For Each tmpWb In Workbooks ・・・・・ Next
じゃあボクは上から失礼・・・
>>338 質問の焦点がバラけ過ぎで何を知りたいのかわかりませぬ。
>>338 CreateObjectしたExcelで
オープンしたブックのコレクションは
For Each tmpWb In objXls.Workbooks
・・・・・
Next
で取得かな
てか
直前にオープンしたブックは 変数 wb を使えばいいんじゃないの
345 :
デフォルトの名無しさん :2010/12/18(土) 23:38:30
>>344 どうもありがとうございます。
実は、とある処g理でchangeイベントが発生する度に参照したいブックがあり、
そこそこ大きいファイルなので毎回open→closeは無駄。
しかも見せたくないので普通にopenしたくない。
なので参照元ブックopen時に1回だけopenして、後はchangeプロシージャー
内でそのオブジェクトを取ろうと思ったのですが、
For Each tmpWb In Workbooks
では取れなかったので質問させて頂きました。
今回は回答して頂きましてありがとうございました。
大変助かりました!
>>334 vbaって整数型は符号付きだからね
何したいのか、分からんけど、vba以外を使えばって感じかな
例 Dim a As Long On Error Resume Next a = 1 / 0 If Err.Number <> 0 Then MsgBox Err.Description End If
>>337 Rangeというのは、ひとつあるいは複数のセルを示した『矢印』と
考えれば納得いくかも?
実際、特異だとは思う
WorkSheetの中にはWorkSheetは無いけれど、Rangeなら
For Each rngEach In rngData
とか書けるし、『Rangeの中のRangeの中のRangeの中の・・・』と
無数に入れ子に出来る(RangeオブジェクトのRangeプロパティはRangeを返す)
a=a+1を乗り越えたやつなら理解できるだろ。
最近はBASICも知らず いきなりVBAってやつも多い
いや普通は知らんだろ BASICが必須科目だったのってせいぜい第一次マイコンブームの頃の話だし 数年後にはC言語が主流になってたし
VisualBasicは、元々 Microsoftが開発したものではなく 他社から買収したものである 豆知識な
355 :
デフォルトの名無しさん :2010/12/20(月) 08:11:38
>>336 errorがあったかなかったかを判定できれば何でもいいけど
>>355 エラーの有無はErrオブジェクトで判定できる
例
If Err.Number Then MsgBox("エラー発生")
discription
358 :
デフォルトの名無しさん :2010/12/20(月) 20:54:05
教えてください。 ブックオープン時にファイルを以下のように開いて、 このWorkbook_Open内で開いたブックオブジェクトを getObjectTestサブルーチンで取得するにはどうしたら 良いか教えてください。 よろしくお願いします。
359 :
デフォルトの名無しさん :2010/12/20(月) 20:56:12
Sub Workbook_Open() Dim xls As Object Set xls = CreateObject("Excel.Application") xls.Workbooks.Open(ファイル名) End Sub Sub getObjectTest() End Sub
>>359 いくつかあるが、xlsをPublic変数で宣言して
====標準モジュール
Public xls As Object ' (or Excel.Application
Public xlsBook As Object '(or Excel.Workbook
Sub getObjectTest()
MsgBox xlsBook.Name
End Sub
===ThisWorkbookモジュール
Sub Workbook_Open()
Set xls = CreateObject("Excel.Application")
Set xlsBook = xls.Workbooks.Open("C:\AAA\Test.xls")
End Sub
361 :
デフォルトの名無しさん :2010/12/20(月) 21:52:03
>>360 どうもありがとうございます。
素人で申し訳ないですが、Workbook_OpenでxlsBookに
ワークブックオブジェクトをセットしてWorkbook_Open
が終わっても、xlsBookにセットされた値は有効なんですか?
static以外の変数はサブルーチンが終わったら開放される
と聞いたことがあるので。
362 :
360 :2010/12/20(月) 22:03:05
>>361 >static以外の変数はサブルーチンが終わったら開放される
360のコードを実行すればわかると思うが、、
実行してないにゃぁ。。
Publicを調べてみること。
363 :
デフォルトの名無しさん :2010/12/20(月) 22:17:14
>>362 重ね重ねすみません。
実行できる環境が学校にしかないので。
Publicについて調べてみます。
ありがとうございました!
VBAは遅いから、パブリック宣言はできるだけ少なくした方がいいよ 20個とか宣言したら、激重い
そうか? 20個くらいなら普通に使ってるが。 まぁ、間違い無くスコープを意識した方が良いとは思うけどね。 敢えてPublicを使うと言う明確な意思があるなら、使って構わないかと。 良く分からないからPublicってのはダメだね。
367 :
デフォルトの名無しさん :2010/12/21(火) 23:22:40
こんにちは、教えて下さい。 例えば 30秒毎に、セル(A1からA3)のデータを抽出し、B1からB3に 順に表示することはVBAで可能でしょうか? できるのであればそのプログラムをご教授いただければ嬉しいです。 宜しくお願いします。
368 :
デフォルトの名無しさん :2010/12/21(火) 23:36:36
>>367 できます
sleepとRangeでぐぐりましょう
1分も有れば完成しますよ
Declare Sub Sleep Lib "kernel32" (ByVal ms As Long) Sub test() For r = 1 To 3 Sleep 30000 Cells(r, 2) = Cells(r, 1) Next End Sub
370 :
デフォルトの名無しさん :2010/12/22(水) 00:15:52
>>367 です。
早速のレスありがとうございます。
私の言葉足らずで申し訳なかったのですが、
>>369 さんのだと
・sleepを使うと他の作業もsleepしてしまうので止まらないようにする
・30秒毎に全部同時に抽出&表示
することができないかな?ということです。
お分かりになる方いましたらよろしくお願いします。
30秒ならWaitのほうがDoEvent
>>370 「だいたい」30秒でいいならsleep 30000でもいいけど、
きっちり30秒間隔でやりたいなら、時刻を覚えておいて30秒を足していくとかしないと
Public n ' 基準時刻
Sub timer_start()
n = Now
main
End Sub
Sub main()
Dim a()
a = Range("A1:A3")
Range("B1:B3") = a
n = n + TimeValue("00:00:30")
Application.OnTime n, "main"
End Sub
郵便局で買取してくれないのっておかしいと思う
>>365 初めて聞いた、理由は?
20で遅くなるってありえないでしょ。
定数は全部Const.batに放り込んでそれだけで100個とか普通だし。
365のPCが激糞なだけでは? それか他の原因で重くなっているのをそれにこじつけているだけとか
376 :
デフォルトの名無しさん :2010/12/22(水) 10:29:21
>>372 レスありがとうございます。
こんなに短いプログラムでできるなんて!
早速試してみます(*^_^*)
こんばんは。教えてくだい。 G列のハイパーリンクが張ってあるセル(例えばG30)をクリックすると I列の同じ行のセル(I30)に今日の日付が挿入される物を作りたいです。 このようなことか可能ですか?宜しくお願いします。
一行でできるだろ? 小学生じゃないんだから、宿題の主旨を示せ。 小学生ならあやまる。
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink) Cells(30, 9) = Date End Sub とか
>>379 挿入だから
Cells(30, 9) = Cells(30,9).Value & Date
じゃね?
裏技で、アクセス解析からデータ引っ張るとか。
>>377 G列でハイパーリンクの設定してあるセルは、ひとつ(G30)だけか
リンク先は、I30か、違うのか
これだけでもコードが違ってくる。(ちょこっとだが)
質問者のレベルであれば
>>378 の言うように、実際のものを俎上に!
>>379 こういうことですか?
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'選択セルが一つ、G列を選択、ハイパーリンクが張られている場合
If Target.Count = 1 _
And Target.Column = 7 _
And Target.Hyperlinks.Count > 0 Then
'同じ行のI列に日付を挿入
Me.Cells(Target.Row, 9) = Date
End If
End Sub
>>377 ブックマークの管理か?
リンク先がURLで縦一列に並んでるなら
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
Selection.Offset(0, 2) = Date
End Sub
リンク先がワークシートのセルだとちょっと面倒
俺には無理だ
>>384 引数Targetを使えば、
リンク先(URL,Folder,Cellなど)は考慮に及ばず、だと思うが。。
G列ハイパークリックで、同行I列に今日を入れる場合
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
If Target.Range.Column = 7 Then
Target.Range.Offset(0, 2).Value = Date
End If
End Sub
リンク先が"Cell"の場合だけ処理したいなら、
それを判定するコードを追加するだけ。
リンク先が"Cell"で、I列に限らず
そのリンク先に今日を入れる場合も似たようなもの。。
ところで、質問者はどこ行ったんだぁ。
グリードアイランドみたいなもんか
配列の代入について教えてください。(XPSP3、Excel2002) Array関数で複数値を格納したDataについて、条件があったDataだけ2次配列Mtrxに代入しています。 真ん中あたりのある For Each 〜 Next を使わないで他にいいやり方はないでしょうか? Cntは最大20ほどになります。 Cnt = 0 For i = 0 to 10000 (中略) Data = Array(a,b,c,d,e,f,g,h) (中略) cond = True (中略) If cond = True then k = 0 For Each Item In Data Mtrx(k, Cnt) = Item k = k + 1 Next Cnt = Cnt + 1 Next i (中略) For m = 0 To Cnt For k = 0 To 7 Cells(Rec, k).Value = Mtrx(k, m) Next k Rec=Rec + 1 Next m
Mtrxを2次元配列じゃなくて配列の配列にすればいいんじゃね
>>388 もしかして探してるのはUboundか?
配列変数じゃなくてワークシートにどんどん入れてくとか
それなら一気に代入できるし
>>388 なんだかよくわからんがこういうことか?
ジャグ配列に入れる方法もあるけどそっちが速そうだが。
Dim Count as long
Dim i as long
Dim ArraySize as long
For i = 0 to 10000
(中略)
Data = Array(a,b,c,d,e,f,g,h)
ArraySize = Ubound(Data) - Lbound(Data) + 1
(中略)
If Condition then
Count = Count + 1
Cells(Count, 1).resize(1, ArraySize).value = Data
End If
Next i
392 :
388 :2010/12/25(土) 08:55:17
やりたいことは (1) シートAの1行20データから8データを抽出、Dataに格納 ←Array関数 (2) シートBにDataを転載する ←これが抜けていました (3) (1)-(2)を最大10000行分繰り返す (4) 条件にあったDataは一旦2次配列に格納、(1)-(3)処理後シートBの続きに転載 今後Dataを分ける条件が増えた場合の転載行の管理が面倒と考え、 配列を使えばと思いました。 Array化したDataを2次配列に代入するところでうまくいかず、 For Each〜Next でゴリゴリやっていますが、他にいい方法があればと 質問しました。
>>392 データに差し支えなければサンプルUPしてみてよ。
エスパーってみる。こういうことがしたいんじゃないかと。 Dim Data(2) Data(0) = Array(1, 11, 111) Data(1) = Array(2, 22, 222) Data(2) = Array(3, 3, 333) With WorksheetFunction Range("A1:C3").Value = .Transpose(.Transpose(Data)) End With そもそも、ステップ(1)でArray化しなくて、最初から二次元配列に 入れておけばいいんじゃないか?
2次元配列のペーストは速いね。 ソースは煩雑になりがちな気がするけど。 セルと配列では 0 base と 1baseの違いもウザイ。 Redim Preserve とかコスト高いイメージだけどどうだろうか。
たまにVBA書くと楽しいな。
>>395 は何やってんの?
AdvancedFilterで一瞬なんだが?
>>398 配列なんて必要ないよ。
402 :
398 :2010/12/25(土) 20:50:39
>>401 配列が必要かどうかじゃなくて
「ADOがすげー速い、、」ただその一点に対してのコメント
ところで、Application.Transpose
xl2000では制限があって要素数が多いと不可。
ま、今どきxl2000を使ってるのがいるかどうか分からんが。。
>>402 別にすげーって程じゃないじゃん、普通だろ?
AdvancedFilterの方が速いし。
>>395 は
>>392 を満たすだけならまわりくどいが、
ADOのRecordSetは色々と使い道がある。
別にプロバイダ経由しなくても、メモリ上にいきなり持てるよな。
SQLちっくにSortとFilterは使えるし、XMLやバイナリでシリアライズできるし、
わりと使える。
405 :
デフォルトの名無しさん :2010/12/25(土) 21:48:07
>>397 >
>>395 > 知ってると思われるが、開いてるBookへのADO接続は
> バージョンによってメモリーリーク有り。
メモリリークはするんだけど、開いていないエクセルファイルに対するSQL(ADO)は
うまくいかない時がないか?経験則だけど
単純にデータを取ってくるだけなら問題が出たことないけど、
SQL上で文字列の結合(フィールドの結合?)をしたりするときに
データファイルが開いてない時には結合されるフィールドの結果がNULLになる時がある。
結果Recordsetの数が少ないときは問題なさそうだし、
データファイルが開かれている時にはこの問題がでたことはない。
#データファイルとVBAを実行しているファイルは別ファイル
原因が分からないから、SQL上でcsv文字列を作ったりするときは諦めてデータファイルを開くコードも入れてる
406 :
デフォルトの名無しさん :2010/12/25(土) 23:12:26
教えて下さい。 例えばbook1のa1からa5のデータでー3以下・3以上のデータ行を book2のb2に常に新しい抽出データを表示し、古いのは下にしていく プログラムを教えて下さい。 よろしくお願いします。
なんだかどのタイミングで抽出して、 古くなるのかわかりづらい話だな。
>>403 手数を掛けてすまん。
先の書き方ではそう取られても仕方ないな。
配列の話をしてるときに
「ADOがすげー速い」というのがあったから
「うんにゃ、配列が速い」と言いたかっただけ。
>>397 ,
>>405 メモリリークの情報、ありがと。頭の隅に入れとく。
Excel2007で仕事で使うマクロファイルを作っているんだけど、 他のシートを検索してそのセルをペーストさせる処理を入れたあたりから、コンボボックスいぢるたびに「メモリ不足です。完全に表示できません。」というExcelのポップがあがるようになった。 調べたらExcelの仕様っぽいんだけれど、これってどうやって回避できる? 試しにExcel2010の試用版をインストールしても相変わらずだし、もう頭抱えてる。 Excelは最新バージョン、OSはビスタです。
>>409 仕様っぽいって、下記サポート情報のこと?
「ズームが設定された Excel シートのコンボ ボックスや
リスト ボックスを操作すると メモリ不足が発生する」
http://support.microsoft.com/kb/842231/ja これ2010でも未対応のようだから、100%で表示するしかないと思ふ。
これでなかったら、「仕様っぽい」の根拠を提示すると同時に
処理内容をも少し具体的に提示してみたらどうだらう。
さすれば、誰からか目から鱗のアドバイスがあるかもしれん。
411 :
410 :2010/12/26(日) 09:36:04
連続投稿、すまん。
いま
>>410 で提示したサイトの再現部分をxl2010やってみた。
エラーが出た、が、ダメもとで、
リストのあるシート(Sheet1)のサイズを100%にしてみたらエラーなし
参考になれば。。。
409です。「Sheet1」シートに配置したコンボボックスで染料名を選択し、その染料の色データを「List」シートからコピーさせています。 以下、コンボボックスのコード Private Sub Cmb1c_Change() Dim FoundCell As Range, FirstCell As Range, SecondCell As Range x1c = Cmb1c.Value cad1(6) = "I8" Set FoundCell = Worksheets("List").Cells.Find(what:=x1c) If FoundCell Is Nothing Then MsgBox "見つかりません" Exit Sub Else Set FirstCell = FoundCell Set SecondCell = FirstCell.Offset(, 1) SecondCell.Copy Range(cad1(6)) End If End Sub 「List」シートにはB列に染料名、C列にその色をグラデーション表示しています。グラデーション使ってるのが悪いのかな・・・
>リストのあるシート(Sheet1)のサイズを100%にしてみたらエラーなし 411のコメントを見落としてました。スミマセン。 サイズを100%にしたら無事解消しました。ありがとうございます。 本当はもっと大きなサイズで使いたいのですが、ここはもう妥協するしかないですね。
>413 表示倍率は100%のまま、フォント、行の高さ、列幅を大きくして、 印刷の設定を逆に小さくしたらダメですか?
415 :
デフォルトの名無しさん :2010/12/26(日) 22:03:21
>>406 です。
わかりにくくてすいません。
ちょっと書き直しますと
例えばbook1のa1からa5のデータは常に数字が変わっています。
そのa1からa5のデータから-3以下・3以上のデータを抽出し、
book2のb2に抽出データをリアルタイムで常に表示し、
抽出した古いデータは1行ずつ下がっていくプログラムを
できますようならお願いしたいのです。
どうかよろしくお願いいたします。
>>415 下がるタイミングを決めないと。
下がるイベントの発生条件は?
417 :
デフォルトの名無しさん :2010/12/26(日) 22:48:51
>>416 抽出データが発生して、それをbook2にコピーする前です。
>>415 sheet A のWorksheet_Changeイベントに次のように書くとか。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim v
If Intersect(Target, Me.Range("A1:A5")) Is Nothing Then Exit Sub
For Each v In Target
If v <= -3 Or v >= 3 Then
Worksheets("B").Range("B1").Insert Shift:=xlDown
Worksheets("B").Range("B1") = v
End If
Next
End Sub
シート間じゃなくてブック間か。
420 :
デフォルトの名無しさん :2010/12/26(日) 23:23:47
>>418 ありがとうございます。
何か思ってたより難しい言葉が使われてて
短いプログラムで感動してます(*^_^*)
今その後をやってまして、
実は抽出元データに
=IF(ISERROR(),"",()
を使って#DIV/0!を表示しないよう空白になるように設定してます。
ですが、データの中に1つでも空白(#DIV/0!)部分があると
オートフィルターで抽出できません。(エラー)
どうすればいいでしょうか?
421 :
388 :2010/12/27(月) 08:38:49
いろいろ参考になりました
>>395 ありがとうございました
422 :
デフォルトの名無しさん :2010/12/27(月) 13:52:53
423 :
デフォルトの名無しさん :2010/12/27(月) 22:15:14
>>415 です。
やりたいことをまとめますと
例えばbook1のa1からa5のデータは常に数字が変わっています。
そのa1からa5のデータから-3以下・3以上のデータを抽出します。
book2のb2に抽出データを常に表示しますが、
抽出データが発生して、それをbook2のb2にコピーする前に
その前に抽出した古いデータは1行下がります。
全ての処理は終わることなく続きます。
こんなプログラムを作っています。
しかし、データ元の数字には#DIV/0もあって、
これを
IF(ISERROR((式),0,(式)
を使って0にしてるのですが、
実行時エラー「型が一致しません」と出て先にすすみません。
エラーを数字の0にしてるから大丈夫じゃないのかと思ってますが
駄目なんでしょうね(+_+)
どなたかわかる方いましたらプログラム・アドバイスお願いします。
もうちょっと放置したらさらに後だししてくれるとえすぱー
>>423 >>418 の改変
Private Sub Worksheet_Change(ByVal Target As Range)
Dim v
Dim modRange As Range
Set modRange = Intersect(Target, Me.Range("A1:A5"))
For Each v In modRange
If IsNumeric(v) Then
If v <= 3 Or v >= 3 Then
Worksheets("B").Range("B1").Insert Shift:=xlDown
Worksheets("B").Range("B1") = v
End If
End If
Next
End Sub
これはシート間の例だけどWorksheets("B")をうまくBook2のシートに変えてあげればいいんじゃないの。
426 :
デフォルトの名無しさん :2010/12/28(火) 01:00:35
ありがとうございます。 標準モジュールにコピーして実行しましたが何も反応無しです。 F8キーでコマ送りしても反応無しです(+_+) エクセル2003を使ってますがこれで作動しますか? それか他に問題が?
vの判定まてw
標準モジュールじゃなくてシートに貼るんだろ・・・。
429 :
デフォルトの名無しさん :2010/12/28(火) 01:28:33
標準モジュールじゃなかったのですか!?(+_+) ごめんなさいシートというとワークシートしか思いつかないです。 文字をコピーしただけに見えますが、何かやり方が!? 他にメニューから「シート」を探してみましたがわかりません・・・
ループの前に is Nothing 判定もいれろ
>>429 VBEditorの画面で対象のシートをダブルクリックする
横に新しいモジュールシートが出てくる それがシートモジュール
んで、シートモジュールの上に Generalってあるから▼をクリックするとWorksheetって出てくる
次に右隣のタブにいろんなイベントが出てくるから対象のイベントを選択する
そうすると、モジュールに雛形がでてくる
ここまで説明すりゃ大丈夫だろw
質問者よ、一体どんなコードを使ってるんだ。 何やかやの前にそのコードを提示したらだうだ。 その前に、 A1−A5に、式、が入ってるんなら Worksheet_Changeじゃだめだらう。
433 :
432 :2010/12/28(火) 12:06:48
言葉足らずあり、訂正してお詫び申し上げる。。 A1−A5に他のセルの参照式が入ってるだろうから Worksheet_Changeで●A1−A5●をIntersectしちゃめだらう。 IF(ISERROR((式),0,(式) の式の対象となってるセルをチェックせねば。 以上。
式がもともと入っているのではなく、エラーを回避したいがために 入れたとエスパーしてみるが。
さうか、さうなら、再度、お詫び申し上げねばならんが。。。
別の箇所にあるデータを更新すると数式で加工するんだろうな 初めから数式使わないのがベストじゃね?
437 :
デフォルトの名無しさん :2010/12/28(火) 23:29:25
>>423 です。自宅PC今起動しました。
>>431 さん。シートモジュール出し方わかりました。ありがとうございます。
以下はシートモジュールの意味が分からない前、自分が作ってる途中のです。
わがまま言ってすいません。以下のを指摘・改良してもらうと、
自分も理解できて完成以降も自力で改善できそうなのですが・・・
Sub 条件抽出()
Select Case Range("a1:a5").Value
Case Is >= 3
Windows("book2").Activate
Rows("2:2").Select
Selection.Insert shift:=xlDown
Range("b2").Select
Case Is <= -3
Windows("book2").Activate
Rows("2:2").Select
Selection.Insert shift:=xlDown
Range("b2").Select
Case Else
End Select
End Sub
これにオートフィルターとコピー・貼り付けを足す作業しようと思いますが。
エラー出まくりで中々進まず(+_+)
むだにselectとActiveを使うのヤメれ
439 :
デフォルトの名無しさん :2010/12/28(火) 23:40:58
あれ?タブスペースが抜けちゃってる何でだろう? 続きです。 a1からa5に入ってる式は IF(ISERROR(((F6-E6)/E6),0,((F6-E6)/E6) です。 VBA独学で始めてまだ2週間です。
>439 2ちゃんねるでは、レスの各行の先頭にあるタブや半角スペースは無視されます。 全角スペースは有効です。インデントを明示したいときは、全角スペースを入れるといいです。
超初心者な質問ですみません。他に見つからなくて XPpro sp3 excel2007です 今日の日付と曜日をA1に取得するのに下のようなのを使ってます Sub 日付取得() Worksheets("sheet1").Cells(1, 1) = Date & "(" & WeekdayName(Weekday(Date), True) & ")" End Sub すると 2010/12/29(水) って表示されます。この曜日の1文字だけ、もし”日”の時は赤にしたいんですがどうすればいいでしょうか? 2010/12/29 (水) ↑ この1文字だけ”日”の時は赤に変えたいです
セル内の関数でどうぞ。
443 :
441 :2010/12/29(水) 02:43:13
InStr関数とCharacters関数でできました ググり方が足りなかったです ごめんなさい
444 :
デフォルトの名無しさん :2010/12/29(水) 17:30:53
>>431 >次に右隣のタブにいろんなイベントが出てくるから対象のイベントを選択する
>そうすると、モジュールに雛形がでてくる
右隣のタブに出てくる中で、どれが適したイベントなのかわからなかったです。
446 :
デフォルトの名無しさん :2010/12/30(木) 00:06:15
>>445 ありがとうございます。
chageにコピーしてF8でコマ送りしても無反応です・・・
upしたらみんな見てくれると思う
Activeセルが特定のRange内にあるかどうか判定する方法をご教授ください。
.row
>>448 これこれ、これです。お世話になりました。
>406,415,417,420,423,426,437,439,446 A1〜A5のデータが常に変わっている とはいうものの、ここには数式が入っている。 >439では >a1からa5に入ってる式は IF(ISERROR(((F6-E6)/E6),0,((F6-E6)/E6) が入っている というけど、全部この式が入っているはずがない(A1〜A5全部同じ結果になるよ) というか、この式を試そうとしたら誤りになった。カッコの位置がおかしい。正しくは =IF(ISERROR((F6-E6)/E6),0,((F6-E6)/E6)) になるはず。エスパーして、 A2セルには =IF(ISERROR((F7-E7)/E7),0,((F7-E7)/E7)) ・・・(中略) A5セルには =IF(ISERROR((F10-E10)/E10),0,((F10-E10)/E10))というふうに なっているものと仮定する。そしたら、VBAでチェックすべきセル範囲はE6:F10になる。 Set modRange = Intersect(Target, Me.Range("A1:A5")) を実行しても、modRangeはNothingのまま。 しかも、一度にE6:F10をチェックすることはマズイ。(実際やってみた) A1〜A5の内容が上から順に1,2,3,4,5となっている場合に、E6かF6のどちらかの セルに入力した結果、A1セルが−3になった場合、抽出対象はA1〜A5のうち、A1だけでなく、 A3,A4,A5も含まれることになるから、計4セル分ずれることになる。 最初の質問ではA1〜A5のどれか内容が変化したセルの値が−3以下or3以上のときに・・・・・と あったので、A1の値の元となるE6:F6、A2の値の元となるE7:F7、(中略)A5の値の元となる E10:F10というように5とおりに処理を分ける必要がある。で、結局次レスのマクロでOK。
453 :
452 :2010/12/30(木) 13:47:48
Private Sub Worksheet_Change(ByVal Target As Range) Dim x As Integer, y As Long, v As Variant MsgBox (Target.Address) '入力したセルアドレスを表示(デバッグ用) x = Target.Column y = Target.Row If x = 5 Or x = 6 Then 'E列かF列 If y >= 6 And y <= 10 Then '6行目〜10行目 v = Cells(y - 5, 1).Value '値をチェックするのはA列 If IsNumeric(v) Then If v <= -3 Or v >= 3 Then Worksheets("B").Range("B1").Insert Shift:=xlDown Worksheets("B").Range("B1") = v End If End If End If End If End Sub E6かF6に入力したらA1だけチェックして−3以下または3以上のとき抽出する。 他のセルの場合も同じ。
454 :
デフォルトの名無しさん :2010/12/30(木) 22:11:06
>>452 カッコの位置はコピーする時の何かで間違ってしまったようです。
A5セルまでに入ってる式当たりです!
>Set modRange = Intersect(Target, Me.Range("A1:A5")) を実行しても、modRangeはNothingのまま。
この辺りから私には言葉が難しく理解できません・・・。
ありがとうございました。
無料RPG製作ツール「ロープレジェネレーター」
http://sekisekki.net/index.htm 直感的操作で簡単なゲームが作れます。 簡単に配布可能な状態に出力することができます。
(HSP製のソースコード付きで、スクリプトの知識があれば自由度の非常に高いカスタマイズ
ができます)
他にも仲間預かり機能(100人も)や、仲間の状態/状態異常を細かく設定できたり、
乗り物が作れたり、ゲーム中に画像を差し込んだり、回転やフラッシュなどのエフェクト
なんかも簡単に作れる様です。
移動は矢印キーの他に、キャラがマウスを追っかけたりするとのこと。
戦闘はデフォだとドラクエ系。
他にはオートアクションというのがあってオリジナルシステムの製作に役に立つかも
しれない機能です。これは、マップエディタで設定することで、「マップに入った時・
出た時・一歩歩いた時・戦闘開始前」に自動的に実行されるアクションを設定できる
機能です。
■他にもいろいろ進化中。要望や分からないことは掲示板へどうぞ。
どんなゲームが作れるかはこれを見れくれ。HSPのカスタマイズはしてないとの事。
「眠られぬ獅子〜序章〜」
http://www.freem.ne.jp/game/win/g02773.html
456 :
452 :2010/12/30(木) 23:25:26
>454
>453のマクロを実行してみるばわかるはずだけど、E6セルに入力した時点で
マクロが起動して、メッセージボックスに $E$6 と表示されるはず。
http://www.moug.net/tech/exvba/0050131.htm を見てもらうと
〜引数に指定したRangeオブジェクトへの参照の共通部分への参照を返します〜
と説明がある。入力したセル位置(Targetに設定されている$E$6)と、マクロ内
に記した A1:A5 には共通部分がないので、結果は Nothing になる、ということ。
同じ事を、自分のマクロでは Target の列位置x と行位置y がそれぞれの範囲内で
あるかどうかでチェックしている。ただしTargetのセルは1個だけという前提。
(コピペでもしない限り、セル1個ずつの入力しかできない)
457 :
デフォルトの名無しさん :2010/12/31(金) 00:08:12
>>456 え〜と・・・今の状況を言いますと、教えてもらったプログラムをコピーしても作動しません。
おそらく
>>431 のやり方が初めてで、プログラムの貼り付け先が間違ってるとかだと思います。
以下貼り付け先
>VBEditorの画面で対象のシートをダブルクリックする
VBAprojectメニューのsheet1ってことでいいのでしょうか?
>横に新しいモジュールシートが出てくる それがシートモジュール
これはわかりました
>んで、シートモジュールの上に Generalってあるから▼をクリックするとWorksheetって出てくる
Generalをworksheetに変更できました。
>次に右隣のタブにいろんなイベントが出てくるから対象のイベントを選択する
changeってことでいいのですよね!?
>そうすると、モジュールに雛形がでてくる
そこに教えてもらったのをそのまんまコピーしました。
メニューの再生ボタンを押すとマクロポップアップウィンドウが出て、
過去に作ったマクロファイルと実行・編集ボタンやらが出てきてしまいます。
そして再生ボタンではなくF8を押しても無反応です。
教えてもらったプログラムは、並行して自分で作ってるのと同時に作業してます。
(これも原因?)
>>457 changeイベントはAlt+F8などのマクロで実行するものではないです。
シートモジュールのシートの内容が変わった際に自動的に稼動します。
コードにブレークポイントを付けておけば動きがわかるはずです。
>457 間違って他のシートのマクロを消してしまうとまずいので、ひとこと。 すでに何か書いているマクロを消すことではありません。 新しく増やしたシート(マクロはまだ何もない状態)に、さきほどの3行だけ存在する状態でテストするということ。
461 :
デフォルトの名無しさん :2010/12/31(金) 00:48:42
$A$1出ました
>461 了解 今、次の解説を書いているところ、しばし待って
>457
ひながたを作らなくても、シートにマクロが何もない状態で
マクロソースをコピペしても動きます。
さっきの3行をまるごと削除してから、>453のソースをコピペしてください。
http://www.dotup.org/uploda/www.dotup.org1330223.png の画面と同じになるはず。VBEの画面は閉じて、当該シートのA1、E6、F6セルに
式と値を入れてみてください。
A1に式を入力したときにメッセージボックスに$A$1、
E6に数字を入れたときに 同上 $E$6、
F6に数字を入れたときに 同上 $F$6、
A1セルの数字が抽出対象であったとき、シートBのB1にA1セルの内容が転記されているはず。
(B列の内容が1行ずつ下にずれた状態で)
ふたつのシートを横に 整列 させるとよくわかるはず。うまくいったら、 MsgBox (Target.Address) '入力したセルアドレスを表示(デバッグ用) の部分は削除してもいいし、先頭に ' を付けてコメント化したらいいです。 ところで、本来動かしたいシートで動かすマクロがこれひとつだけなら、 あなたが今書いている作成途中のマクロ『Private Sub Worksheet_Change(ByVal Target As Range) で始まるもの』とは、同居はできないので消してください。 Alt+F8から動かすマクロ『Sub マクロ名 で始まるもの』は同じシートに同居できます。
465 :
デフォルトの名無しさん :2010/12/31(金) 01:21:23
>>463 おお!!
動いた!!
ありがとうございます。
>465 それじゃ、Good Night!
467 :
デフォルトの名無しさん :2010/12/31(金) 01:26:56
>>464 先が明るくなりました^^
同居できないマクロは同じタイミグの時に動くマクロだけですか?
それとも、その前後に入れてあるマクロも全部ですか?
468 :
デフォルトの名無しさん :2010/12/31(金) 01:28:21
>>468 これどう?
http://www1.axfc.net/uploader/Sc/so/189319.zip A1:A5に他のセルを参照する式が入っている場合。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
For Each r In Me.Range("A1:A5")
If Not Intersect(r.DirectPrecedents, Target) Is Nothing Then
If IsNumeric(r.Value) Then
Worksheets("B").Range("B1").Insert Shift:=xlDown
Worksheets("B").Range("B1") = r.Value
End If
End If
Next
End Sub
オートシェイプを設置するときに ActiveSheet.Shapes.AddShape(msoShapeOval, x, y, sizex, sizey).Select ですがこれだとアクティブになってしまいます。 ならないようにはどうすればいいでしょうか
>>470 Selectしてるからアクティブになるのは当然だらう。
で、selectと引数を囲ってる()カッコを除去して、
ActiveSheet.Shapes.AddShape msoShapeOval, x, y, sizex, sizey
これでいいと思うが。。
472 :
デフォルトの名無しさん :2011/01/01(土) 22:35:21
>>468 です。
>>453 今、詳細を見て自分なりに勉強してます。
> v = Cells(y - 5, 1).Value
この式の()の中のy-5,1の意味が分かりません(+_+)
教えていただけると助かります。
473 :
デフォルトの名無しさん :2011/01/01(土) 23:01:26
↑ あっ。今、理解できました(^^ 昨日から何時間も悩んでたけど、簡単なことだった・・・
474 :
464 :2011/01/01(土) 23:17:07
>467,472 新年早々からお仕事ですか、おつかれさま&あけおめ >同居できないマクロは同じタイミグの時に動くマクロだけですか? >それとも、その前後に入れてあるマクロも全部ですか? 新規にシートを追加して(新規ブックでもいいけど)以下のマクロが作れるか試してみてください。 Private Sub Worksheet_Change(ByVal Target As Range) msgbox("あ") End Sub Private Sub Worksheet_Change(ByVal Target As Range) msgbox("い") End Sub Private Sub Worksheet_Change(ByVal Target As Range) msgbox("う") End Sub たぶんできないと思う(同じ名前は使えないとかなんとか表示されてエラーになった) シートの何かのセルに入力した(削除でも貼り付けでもいいけど)タイミングで起動できる マクロの名前はシートにひとつしか許されないはず。 だから、先頭(Sub とか Private Sub とか Function の行)が同じものが同居できない だけで、Sub macro_A() Sub macro_B() みたいに名前が付けられるものや、別のイベントを 受けて起動するものは同居できます。 上記の例で言えば、あるひとつの処理(Worksheet_Change)をうけて、複数の処理を行いたい場合は、 Private Sub Worksheet_Change(ByVal Target As Range) 処理 A 処理 B 処理 C End Sub みたいにするといいです。で、処理A〜Cは、シートではなくモジュールに書くといいです。
475 :
デフォルトの名無しさん :2011/01/01(土) 23:24:58
>>469 ごめんなさい。まだ
>>453 のプログラム解析中でそこまで行ってません(汗
>>453 問題があります。
セルA1からA5で条件の数字を検出した時に
どの項目の数字が検出されたのかわからないので
BとC列に書いてある項目も数字と同時に検出したいです。
(B列が名前、C列が数字)
それと、複数同時に検出しても1つしかワークシートBに
コピーされないのを、全て同時にコピーしたいです。
何かいい方法はないでしょうか?
よろしくお願いします。
476 :
デフォルトの名無しさん :2011/01/01(土) 23:33:01
>>474 あけましておめでとうございます。年末はお世話になりましたm(__)m今年もよろしくお願いします。
同居の件了解です。
私が作ったのは標準モジュールで本当に簡単なものだけです。
大丈夫そうですね(^^ゞ
477 :
474 :2011/01/01(土) 23:52:56
>476 >どの項目の数字が検出されたのかわからないので Target という変数に入力したセル位置がセットされています。 Private Sub Worksheet_Change(ByVal Target As Range) msgbox(Target.Address) End Sub >463で上記の簡単なマクロをテストしたときに、メッセージボックスに表示されたから わかるはずです。 それとも、抽出(転記)したのがA1〜A5のどれか、知りたいということであれば、 Msgbox(Cells(y-1,1).Address) で $A$1 などと表示できます。$をとりたいなら Msgbox(Replace(Cells(y-1,1).Address,"$","")で。 >BとC列に書いてある項目も数字と同時に検出したいです。 「検出」というよりも、A1〜A5セルの中の抽出したセルの右隣の2つのセル内容も 転記したいということであれば、 Worksheets("B").Range("B1").Insert Shift:=xlDown Worksheets("B").Range("B1") = v の部分を Worksheets("B").Range("B1:D1").Insert Shift:=xlDown Worksheets("B").Range("B1") = v Worksheets("B").Range("C1") = Cells(y - 5, 2).Value Worksheets("B").Range("D1") = Cells(y - 5, 3).Value にしたらできるはずです。
478 :
477 :2011/01/01(土) 23:56:23
>477の変更後の部分の最後の3行は、 Worksheets("B").Range("B1").value = v Worksheets("B").Range("C1").value = Cells(y - 5, 2).Value Worksheets("B").Range("D1").value = Cells(y - 5, 3).Value の方がいいです。(値の転記であることを明示)
479 :
デフォルトの名無しさん :2011/01/02(日) 00:08:02
すごいですね・・・短時間に。
感謝の気持ちでいっぱいです。
寝不足気味なので、
>>478 やったら今日は寝たいと思います。
ありがとうございます。
480 :
477 :2011/01/02(日) 00:40:27
>475 >それと、複数同時に検出しても1つしかワークシートBに >コピーされないのを、全て同時にコピーしたいです。 「複数同時に検出」ということは、E6:F10セルにキーボードから入力ではなく、 貼り付けで入力する場合があるということでしょうか? そういうことであれば、>469さんの方法が最適です。 DirectPrecedents で、計算式の参照元がわかるそうです。(自分は試してません)
481 :
デフォルトの名無しさん :2011/01/02(日) 01:46:35
>>478 まで完了です。ありがとうございます。
>>469 さんのは、どこかを訂正する形で書き換えるってことですよね?
それらしき場所にコピーしたもののエラーばかりで作動しません(+_+)
>481 当方(Excel2003)で試したら、そのままでばっちりでしたよ。>469さんの方法は 複数セルへの対応もできています。 1列2行のセルを貼り付けたら2個、2列1行のセルを貼り付けたら1個のセルを 抽出しました。 >474でも書いたように、Private Sub Worksheet_Change のマクロはシートに ひとつだけしか置けません。>453のマクロと全部置き換えてください。
483 :
デフォルトの名無しさん :2011/01/02(日) 21:00:01
>>482 私のエクセル2003でも
>>469 さんのは作動しました。
>469、>481さんありがとうございます。
ただ3以上、3以下の条件の数字だけを抽出したいので、その条件を
抽出できる
>>453 さんのマクロに繋げられないものかと思って四苦八苦してます。
>483 >469さんのは値範囲のチェックがありませんでしたね。 >469さんのマクロの If IsNumeric(r.Value) Then Worksheets("B").Range("B1").Insert Shift:=xlDown Worksheets("B").Range("B1") = r.Value End If を If IsNumeric(r.Value) Then If v <= -3 Or v >= 3 Then '←追加 Worksheets("B").Range("B1").Insert Shift:=xlDown Worksheets("B").Range("B1") = r.Value End If '←追加 End If にするだけですよ。
485 :
デフォルトの名無しさん :2011/01/02(日) 23:52:11
>>484 なるほど。ありがとうございます。
しかし
>>475 のもう一つの問題が残っているのと
If Not Intersect(r.DirectPrecedents, Target) Is Nothing Then
のとこが私には難しく、後に自分で変更・管理できる自信なく
>>453 をベースに出来上がってきたのでいこうと思います。
>485 >469さんのマクロの Worksheets("B").Range("B1").Insert Shift:=xlDown Worksheets("B").Range("B1") = r.Value を Worksheets("B").Range("B1:D1").Insert Shift:=xlDown ←セル範囲を拡張 Worksheets("B").Range("B1").Value = r.Value ←変更なし Worksheets("B").Range("C1").Value = r.Offset(0,1).Value ←追加 Worksheets("B").Range("D1").Value = r.Offset(0,2).Value ←追加 に変えるだけです。 If Not Intersect(r.DirectPrecedents, Target) Is Nothing Then の部分は、 変更する必要がありません。もし、A1〜A5の式で参照している部分が他の シートになったとしたら、>469さんのマクロでも対応不可ですが、同じシートを 参照しているのであれば、何も変える必要はありません。私(>453)の方は、 A1〜A5の式の参照先セルが変わったら、それに応じて If x = 5 Or x = 6 Then 'E列かF列 If y >= 6 And y <= 10 Then '6行目〜10行目 の部分を変更しなければなりません。>469さんの方が、より汎用性があるということです。 VBAで使う単語 の意味は excel vba と組み合わせて 例えば excel vba DirectPrecedents などとしてググればわかります。
懇切丁寧だな。
488 :
デフォルトの名無しさん :2011/01/03(月) 21:53:09
>>486 なるほど。
参照先セルはこの先変更したいので、その方法が分かって
目から鱗がでるほどです。
とりあえず明日仕事場に持って行って、テスト運用です。
バタバタしてるので
>>469 さんのは明後日以降に書き換えて
使ってみようと思います。
ほんと懇切丁寧で、ここまで来る事ができて感謝です。
その間に色々学べました。本当にありがとうございました。
m(__)m
489 :
デフォルトの名無しさん :2011/01/04(火) 20:51:59
>>488 です。こちらで教わったマクロにちょっと手を加えて、仕事場でテストしてきました。
E列とF列5行〜578行には会社の機械から抽出した数字(整数)がでるようになっています。
G列にはE列とF列のそれぞれの行の計算をした結果(小数点あり)を表示しています。
そのG5には
IF(F5=0,0,(E5-F5)/F5)
の式が入ってます。6行目には6行目の数字が計算されるようになっていて
578行まであります。そして以下のマクロを入れてます。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim x As Integer, y As Long, v As Variant
x = Target.Column
y = Target.Row
If x = 5 Or x = 6 Then 'E列かF列
If y >= 5 And y <= 578 Then '6行目〜10行目
v = Cells(y, 7).Value '値をチェックするのはA列
If IsNumeric(v) Then
If v <= -0.015 Or v >= 0.015 Then
Worksheets("B").Range("B2:D2").Insert Shift:=xlDown
Worksheets("B").Range("B2").Value = v
Worksheets("B").Range("C2").Value = Cells(y, 3).Value
Worksheets("B").Range("D2").Value = Cells(y, 4).Value
End If
End If
End If
End If
End Sub
しかし、シートBに抽出データが入ってきません(+_+)
なぜでしょうか?問題のご指摘していただけると助かります。
適切にme.cellsとかつけた方がいい。
491 :
デフォルトの名無しさん :2011/01/04(火) 20:55:28
↑もっと正確に状況を書きますと E列・F列にテスト的に手動で適当な数字を入れると シートBに抽出されて表示されますが、仕事場の機械からの 数字の計算結果は抽出されないという状況です。
年末からずぅ〜っと続いてんの、これ?
493 :
デフォルトの名無しさん :2011/01/04(火) 22:08:05
すいません続いちゃって。
>>490 さん。どの辺りにme.cellsとかつけるのでしょうか?
>>489 と同じ条件でマクロを組むと
>>469 さんのでいくと
こうゆうことでしょうか?
こちらは手動で適当な数字入れてもワークシートBに抽出されません(+_+)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
For Each r In Me.Range("G5:G578")
If Not Intersect(r.DirectPrecedents, Target) Is Nothing Then
If IsNumeric(r.Value) Then
If v <= -0.015 Or v >= 0.015 Then
Worksheets("B").Range("B1:D1").Insert Shift:=xlDown
Worksheets("B").Range("B1").Value = r.Value
Worksheets("B").Range("C1").Value = r.Offset(0, 1).Value
Worksheets("B").Range("D1").Value = r.Offset(0, 2).Value
End If
End If
End If
Next
End Sub
>>493 のコードを全部削除して、
標準モジュールに以下のコードをコピペして実行せよ
Sub Test()
Dim r As Range
For Each r In Range("G5:G578")
If r.Value <= -0.015 Or r.Value >= 0.015 Then
Sheets("B").Rows(1).Insert Shift:=xlDown
Sheets("B").Range("B1").Value = Cells(r.Row, "E").Value
Sheets("B").Range("C1").Value = Cells(r.Row, "F").Value
Sheets("B").Range("D1").Value = Cells(r.Row, "G").Value
End If
Next
End Sub
VBA習い始めということらしいからごちゃごちゃしたのは抜き。。
つーかExcel買えよ 仕事場の往復じゃ効率悪いだろ
496 :
486 :2011/01/05(水) 15:07:41
>489 そもそもの出発点から確認します。 >E列とF列5行〜578行には会社の機械から抽出した数字(整数)がでるようになっています 機械から抽出した数字がでるというのは、そのパソコンと「機械」がなにかのインターフェース装置 (RS232CとかGPIBとかの)でつながって、キー操作なしで入力されていくってこと? それを確認するには、>459で示した3行だけのプログラムを「機械とつながっているパソコン」で 試してください。入力のあったセル位置の表示がなければ、いくら中身を調べてもムダです。 Private Sub Worksheet_Change(ByVal Target As Range) というプログラムは、キー操作による ワークシートへのなんらかの変更をきっかけに起動するものだから、インターフェース装置からの 入力では起動しないものかもしれません。
497 :
496 :2011/01/05(水) 15:11:43
>495 質問者の自宅にもExcelはあると思う。真夜中の質問が多い。>457-461 のやりとりを見るとわかる。 ただ、何かの「機械」からのデータ入力で起動するマクロなので、自宅で検証ができないのがツライところ。
498 :
496 :2011/01/05(水) 15:22:22
機械からのデータを受けてシートに入力するということは、当該ブックでは なにかのマクロが動いているはずなので、そのマクロがシートに「入力」 しても、Worksheet_Change イベントが発生するんだろうか?
バッチ処理か何かで、そのExcelに書き込んでいるんだろうな。 しかしその詳細は知らないと見える。 DBエンジン経由とかで書き込んでたら、 Worksheet_Changeイベントは発生しないかもな。 そうだとすると辛いところです。
500 :
496 :2011/01/05(水) 17:56:17
>489 自分で試してみたら、メッセージボックスが表示されて[OK]をクリック するまでマクロが止まることに気付き、どこか適当なセルに刻々と表示する 簡単なものを作ってみました。 Private Sub Worksheet_Change(ByVal Target As Range) Application.EnableEvents = False '←イベント受付停止 Range("E1").Value = Replace(Target.Address, "$", "") '←書き込みセル位置はよく考えて Application.EnableEvents = True '←イベント受付再開 End Sub 上記のマクロを、機械とは関係のないPCの新規ブックのシートに書いて試してみてください。 当該シートのどこにデータを入力しても、3行目で指定した場所(例ではE1セル)に入力した セル位置を表示するはずです。 これでうまくいったら、同じマクロを機械のデータを時々刻々と表示しているPCのマクロで 試してみてください。E1セルがまずければ、どこか適切なセル位置を指定すること。 何も変化がなければ、機械のデータを受けてシートに表示するマクロがイベントを受け付けない ように設定していると推測できます。もしくは>499さんのとおりかも。 上記マクロの2行目で「イベント受付停止」としているのは、3行目の書き込みを受けて、また このマクロが起動し、堂々巡りにならないようにしているものです。(マクロ4行目で再開)
501 :
デフォルトの名無しさん :2011/01/05(水) 21:47:35
>>496 さんので理解できました。
仕事場の機械からPCに自動でブレた数字が表示されるようになってます。
仕事場のPCに数字をキー操作でテスト入力したのは表示されるのに、
機械を動かして表示されるのは無反応でした・・・
そういうことだったのですね。
>>497 さんのおっしゃる通りです(^^ゞ
>>500 さん。せっかく書いていただいたのに申し訳ないです。
Worksheet_Changeイベントは発生しないことがわかりました(+_+)
本日残業中、急遽
>>494 さんのマクロ入力。これは機械から抽出成功でしたが、
マクロ再生ボタンを押した瞬間の1回のみの抽出でした。
何秒かおきにこのマクロを起動させて抽出し続けるのが必要と考えてます。
何とかこのあたりを改良できないでしょうか?
これができれば完成です!
>>501 バッチ処理(?不明)がそのExcelファイルに書き込むのと同じタイミングで、
マクロをキックしてもらうしかないね。
処理の記述はWorksheet_Changeイベントじゃなくて、マクロにする必要がある。
あと、キックする方はマクロを実行出来る権限のあるユーザーじゃないと無理かも。
バッチ処理は別の人が作ったものだろうから改変するのは色々と面倒だろうけどね。
まぁ、バッチ処理の方を改変するのなら要件を満たす方法はマクロ以外にもありそうだが。
>501 やはり、そういうことでしたか。定期的にマクロを起動させることはできますが、機械によるデータ入力のタイミングってどういう感じですか? 画面見てたらわかりませんか?タイミング(間隔)は一定ですか?不規則ですか? 不規則な場合、最小間隔よりも短いタイミングでマクロを定期的に動かさないと「データの取りこぼし」が起こります。 時刻指定でマクロを起動させるサンプルとして、別のスレ(Excel総合相談所93)にあったものを紹介します。これは、新規ブックの標準モジュールに書いてください。 (標準モジュールはわかりますよね?) 起動はマクロ一覧から スタート を実行、停止はマクロ一覧から ストップ を実行です。 1秒毎に 時・分・秒 をA1セルに書きます。 Private flgStop As Boolean Sub スタート() flgStop = False 現在時刻 End Sub Sub 現在時刻() If flgStop Then End Application.OnTime Now() + TimeValue("00:00:01"), "現在時刻" '←※ Range("A1").Value = Format(Now, "hh:mm:ss") '←実際にやりたいことをここに書く End Sub Sub ストップ() flgStop = True End Sub ←※で示した行の 00:00:01 を 00:00:05 に変更すると、5秒毎の更新になります。 やりたいこと の部分には、前回起動時とどこが変わったかを検出する部分が必要になります。 書き込もうとしてリロードしたら、>502さんが書いてくれてますが、機械からデータ入力する処理の変更が無理なようなら、私の方法も検討してみてください。
もとの質問を読む気にもならんのは、オレが正月ぼけ だからなのか?
>505 >406 からすでに10往復近いやりとり(自分でも数えてません)があるので、「途中参加」の方は眺めるだけにしておいた方がよろしいかと・・・・・
メールででもやれよ。迷惑だなーって事を書いたんだよ。 自演にも見えて来る。
質問は随時受付中ですよ。
509 :
デフォルトの名無しさん :2011/01/06(木) 00:08:05
迷惑ですね。ごめんなさい(>_<) 指定時刻だと1回のみの実行になってしまうような気がしますが、どうなんでしょう?
510 :
デフォルトの名無しさん :2011/01/06(木) 00:11:35
ここに15秒ごとに抽出をするプログラムがあります。 Public n ' 基準時刻 Sub timer_start() n = Now main End Sub Sub main() Dim a() a = Range("e5:e578") Range("f5:f578") = a n = n + TimeValue("00:00:15") Application.OnTime n, "main" End Sub
511 :
デフォルトの名無しさん :2011/01/06(木) 00:12:37
>510の続き
これにさらに
>>494 さんのプログラムを付け足すことできますか?
Sub test()
Dim r As Range
For Each r In Range("G5:G578")
If r.Value <= -0.015 Or r.Value >= 0.015 Then
Sheets("B").Rows(1).Insert shift:=xlDown
Sheets("B").Range("B2").Value = Cells(r.Row, "E").Value
Sheets("B").Range("C2").Value = Cells(r.Row, "F").Value
Sheets("B").Range("D2").Value = Cells(r.Row, "G").Value
End If
Next
End Sub
適当だと思うところにコピペの試行錯誤してますが・・・
何せ知識が無く、柔軟に言葉を足したりとかできないのでうまくできません。
・順番は15秒抽出プログラムの前に>494さんのプログラムを実行。
・そしてその15秒ごとの動きを繰り返す。
>511
>501の
>本日残業中、急遽
>>494 さんのマクロ入力。これは機械から抽出成功でしたが、
>マクロ再生ボタンを押した瞬間の1回のみの抽出でした。
>何秒かおきにこのマクロを起動させて抽出し続けるのが必要と考えてます。
>何とかこのあたりを改良できないでしょうか?
>これができれば完成です!
について、以下の問題があります。
>494さんのマクロを定期的に動かして完成ではないし、機械からのデータ入力の都度
動かせるようになっても完成ではありません。
E5:F578の範囲のセルが一度に書き変わるのであればともかく、この範囲のセルの
どこか(1個〜複数)が書き変わるということであれば、変更があったセルだけを調べる
部分が必要になります。
もうひとつ、定期的に動かすマクロと、機械が当該シートに書き込もうとする処理が
瞬間的にもぶつかるときに、遅れた方の処理が待ってくれるものなのかどうか。
十分に検証する必要がありますよ。
513 :
デフォルトの名無しさん :2011/01/06(木) 00:34:19
機械からのデータは不規則でかなりの数の更新があって、 全てを抽出できないので、15秒に1回抽出するのみでいいと考えてます(*_*; 15秒に1回、その時の数字を抽出できればいいです。 漏れがあるのは気にしてないです。 宜しくお願いします。
Public n ' 基準時刻 Sub timer_start() n = Now main End Sub Sub main() Dim a() a = Range("e5:e578") '←これは何をしているところなんだろう Range("f5:f578") = a '←同上 n = n + TimeValue("00:00:15") '←ここで次の起動時刻の設定をしてます。Nowは日付・時刻なので、日付が変わってもOK Application.OnTime n, "main" '←ここで次の起動命令(目覚ましセット) Call test '←追加 End Sub たぶん、これでいけるはず。testのマクロも同じ標準モジュールに 同居 させておく。(試してません、あしからず)
515 :
デフォルトの名無しさん :2011/01/06(木) 01:13:47
>514さんありがとうございます。
同じ標準モジュールシートに書くってことですか?
別シートと同じシートに書き込んでやってみましたが、駄目でした(+_+)
タイマーの抽出は今まで通り抽出しますが、
>>494 さんの抽出は15秒ごとに動きません。
1回で終了となってしまいます。
>515 ごめん、Callで呼ばれるプログラムは Private Sub ってしなきゃならなかったかも。 こっちでもテストしてみる(毎日がeveryday な身分なので夜更かしOK)。
>515 こちらでは15秒毎にシートBに出力できてます。 Sub でも Private Sub でも、どちらでもOK。 あくまでも標準モジュールに書いてください。シートの方に書いても動きません。 どうしてもシートに書きたいのであれば、 Application.OnTime n, "main" → Application.OnTime n, "シート名.main" みたいにしないと、エクセルが動かすべきマクロを名前から探し出せません。
>515 タイマーは動いているけど、抽出(シートBに出力)しないってのは、 シートBを表示している(シートBがアクティブになっている)からでは? シートBをアクティブにしてたら、 For Each r In Range("G5:G578") If r.Value <= -0.015 Or r.Value >= 0.015 Then の部分はシートBの方のセルの値をチェックします。 ふたつのシートを並べて表示して、元のシート(E,F,G列にデータがある方)を アクティブにして、やってみてください。
rangeとか、cellとか、どのシートのものか、ちゃんと修飾したほうがいいよ。
>515 >519さんの言うとおり、シート修飾をしてみました。 Public n '基準時刻 Public flgStop As Boolean '停止用フラグ ' 開始するときは マクロ「スタート」を実行 Sub スタート() flgStop = False ' 停止しない 設定 n = Now ' 現在の日付・時刻 Call main End Sub ' 停止するときは マクロ「ストップ」を実行 Sub ストップ() flgStop = True ' 停止する 設定 End Sub ' タイマー処理部分 Sub main() Dim a() If flgStop Then End Worksheets("A").Activate ' 元データのシートに強制的に切り替え a = Range("e5:e578") Range("f5:f578") = a n = n + TimeValue("00:00:15") ' 何秒間隔で実行するか Application.OnTime n, "main" ' 次の起動セット Call test ' 実際に処理する部分 End Sub 続きます
続きです Sub test() Dim r As Range, sh_1 As Excel.Worksheet, sh_2 As Excel.Worksheet Set sh_1 = Worksheets("A") ' 元データのシートをオブジェクト変数に設定 Set sh_2 = Worksheets("B") ' 出力先シート For Each r In sh_1.Range("G5:G578") If r.Value <= -0.015 Or r.Value >= 0.015 Then sh_2.Rows(1).Insert shift:=xlDown sh_2.Range("B2").Value = sh_1.Cells(r.Row, "E").Value sh_2.Range("C2").Value = sh_1.Cells(r.Row, "F").Value sh_2.Range("D2").Value = sh_1.Cells(r.Row, "G").Value End If Next Set sh_1 = Nothing: Set sh_2 = Nothing ' オブジェクト変数の開放 End Sub シートBの方をアクティブにしていても、強制的に元データのシート(例ではシート「A」) に切り替わります。
今きたんだがすごい事になってるな
これはエクササイズです。
524 :
デフォルトの名無しさん :2011/01/06(木) 21:57:55
>>521 さん ありがとうございます!
抽出条件のG列には
=IF(F5=0,0,(E5-F5)/F5)
の式(行はそれぞれに合わせた行)が入っていて、
テストで手動でG列に数字を入れた時は抽出されますが
EかFに数字を入れて計算結果をGに表示させた場合は
抽出されないです。
何かいい方法はないでしょうか?
>524 >520-521を見てもらうとわかりますが、マクロが動くタイミングは n = n + TimeValue("00:00:15") ' 何秒間隔で実行するか の部分です。 E,F列に数字を入れたタイミングではありません。 また、抽出するかどうかは、E,F列の値ではなく、G列の値(計算式があるならば 計算結果)次第です。 If r.Value <= -0.015 Or r.Value >= 0.015 Then からわかるように、G列の 値が条件に合っていますか?また、自動再計算する状態になっていますか?
>>521 やりとりは全然読んでないんだが
> sh_2.Range("B2").Value = sh_1.Cells(r.Row, "E").Value
> sh_2.Range("C2").Value = sh_1.Cells(r.Row, "F").Value
> sh_2.Range("D2").Value = sh_1.Cells(r.Row, "G").Value
これって
sh_2.Range("B2").Resie(,3).Value=r.Offset(,1).Resize(,3).Value
って書けるんじゃないか?
527 :
525 :2011/01/06(木) 23:19:50
>526 質問者がVBA初心者ということなので、極力トリッキーなものは使いたくないのと、 質問者の条件後出しが多く、転記元、転記先が隣接した状態で確定するかどうかも怪しいんです。 (最初の方では、A1〜A5セルの中から抽出したい、と言う話。A1セルの計算式でE5,F5セルを 参照している、という話から、ここまで変わってきた)
528 :
デフォルトの名無しさん :2011/01/06(木) 23:21:43
>>525 タイミングと計算結果次第ということ了解です(^_^)v
しかし反映されないです(+_+)
1つの標準モジュールに
>>520 と
>>521 の順番にそのままコピーして
使ってるのですが、これは順番が逆とか・・・そういうの関係ありますか?
なんかそういうイージーミスが原因のような気も。
>>526 さんアドバイスありがとうございます。書き直してみます。
>528 標準モジュールの中に書く順番は関係ないと思う。 Worksheet_Change で起動するマクロは完全に削除してますか? 関係ないとは思うけど、念のため。
530 :
デフォルトの名無しさん :2011/01/06(木) 23:54:02
>>527 ほんとに申し訳ないです(+_+)
>>529 了解です。他のマクロは他のエクセルファイルにとってありますが
作業中のファイルでは使ってないので大丈夫だと思います。
どうもここからは、仕事場の機械との兼ね合いでしょうか・・・限界が見えてきました。
ここまでアドバイスしていただいた方々ありがとうございましたm(__)m
531 :
デフォルトの名無しさん :2011/01/06(木) 23:57:10
あっ、悪く誤解しないでください。 「限界」の意味は、掲示板のやりとりで独自開発の機械を改善させる難しさのことです。
532 :
デフォルトの名無しさん :2011/01/07(金) 00:03:07
VBA初心者です。ネットで調べてみたけどわかりません。 ブックAとブックBがある。 ブックAのマクロをコマンドボタンから実行すると ブックBを参照して計算した結果を ブックAのボタンのあるシートに書き出す。(ブックBは閉じる) ブックBはユーザに選択させる。また参照するだけで書き換えたりしないので別に開かなくてもよい。 マクロでは計算結果を二次元配列に入れてそれをセルに書き出している。 これのやり方を教えていただければ幸いです。 WinXP エクセル2007 VB6.5
>>532 ファイルを選ばせる Application.GetOpenFilename
開く Open
閉じる Close
534 :
デフォルトの名無しさん :2011/01/07(金) 00:19:13
>>530 です。
自分で改良して完成しました。
完璧です!!ほんとうにどうもありがとうございました!!
2chってすごいです\(^o^)/
>530 マクロ test だけ単独で実行したら、どうなりますか? うまく行くようであれば、>520の部分がおかしいことになります。 自分としては、 a = Range("e5:e578") Range("f5:f578") = a の2行が何が目的なのか、さっぱりわかりません。>510が初出です。 E列とF列に違う数字が入っていても、15秒毎に同じ内容にしているので、G列に =IF(F5=0,0,(E5-F5)/F5) のような計算式があれば、結果は 0 で、抽出はしない(条件に合わない)はず。 「直接G列に抽出条件に合う数字を入れたらうまくいく」から、ここが怪しい。 ここまで書いて、アップしようとしたら、OKだったようですが、 上記のことが原因だったのでは?
>>527 3行で書くにしても行番号を使った悪い方法を教えちゃいかん
年末からのは漸く解決したのか
538 :
388 :2011/01/07(金) 15:57:15
完成した最終形をみたい!
Dim varTest as Variant varTest = ThisWorkBook.WorkSheets(1).UsedRange みたいなRangeを配列に代入するのってMSが公式にサポート表明してたっけ? KB213798ぐらいしか見つからんかったが、いつから出来るようになったんだっけ?
540 :
デフォルトの名無しさん :2011/01/07(金) 19:45:26
ageちゃえ!
でふぉ
>>539 そのKBの対象としてExcel97が含まれているのだから、
少なくともExcel97の時点では既に対応していたんじゃないか?
>>539 Excel95でもl出来たが、せいぜい数千個までのセル範囲だったような記憶がある。
数千個はExcel5だったかも知らん。
それRangeを配列に入れてるんじゃないだろ 配列をバリアント型変数に入れてるだけだ バリアント型変数が配列を取れるのはVBAの仕様 たぶんVBAがEXCELに乗ったときからできてる
んだな。 右辺がThisWorkBook.WorkSheets(1).UsedRange.Valueで2個以上の範囲の場合は2次元配列になってる。 ちなみに下のようにVariant型の配列に代入できるようになったのはExcel2000からだ。 Dim varTest() as Variant varTest = ThisWorkBook.WorkSheets(1).UsedRangeValue
Valueプロパティの省略時の疑問??? ------------------------------------- セルA1,A2 に値が入力されてるとして A1,A2の値をB1,B2へ代入する場合 (1) Range("B1") = Range("A1") Range("B2") = Range("A2") (2) Range("B1:B2") = Range("A1:A2") ▲結果▲ (1)は、OKだが (2)は、B1,B2には何も代入されない ---------------------------------------- なぜだ???
>>547 Excel2007での検証
B1にA1と違う値を入れてやってみれば判るが
(2)は間違いだな。空白に上書きされてる
(2)の式は.Valueの省略とはみなされてないんじゃないか
Range("B1:B2") = Range("A1:A2").Valueならちゃんと動く
>>547 バグに近い仕様じゃないの?
Range("B1:B2") = Range("A1:A2").[_Dfault]と同じ結果になるのが自然だと思うけどな。
ただその症状は昔からよく知られてるからみんな省略しないね。
単にvalue以外になってるだけだろ
Valueの省略と言えばバージョンで動作が異なるものがあったよな。 たとえばComboBox1.List = Range("A1:A10")なんてのはExcel97では動いたそうだが Excel2000以降では右辺に.Valueをつけないと動かん。
>551 >536さんみたいに 行番号を使うのをやたら非難する人はいる(数スレ前にも話題になってた)けど、 .value の省略に目くじらたてる人はあまりいませんね。
Valueはつけよう
dictionaryのkeyにvalue付けなかったら色々ぶちこまれた
>>552 >>536 はごく当たり前の主張だな。
行番号を取得してCellsで使うなんてアホもいいとこだ。
Valueは分かってるやつはつけなくても良い。
俺は必ずつけるけど。
>>554 別にいろいろぶち込まれはしないだろ?
単なる参照だよ。
あぁ言ってる意味が分かったわ。 A1〜10が全部同じ値でも For Each c In Range("A1:A10") dic(c) = Empty Next MsgBox dic.Count なんてやると10になるわな。 dic(c.Value) = Emptyなら1だな。
仕事で初めてVBA関連のシステムを作ることになりました。 そこで質問があります。 複数の各エクセルファイル内のプログラムで使用する共通ファンクションを サーバーに置いて保守(バグ/仕様変更対応)しやすいようにする事を検討しています。 そのような理由からローカルにあるマクロプログラムからサーバーに置いてある 共通プログラムを実行する事を考えているのですが、どのような仕組みが良いか アドバイスを頂けたら助かります。 以下が満たしたいと思っている条件です。 ・サーバーに出来るだけ付加を掛けたくない。 ・ローカルのプログラムからサーバーのプログラムを呼んだ際に、 そのサーバーのプログラムのウィンドウが表示されないような仕組みにしたい。 (裏で動きユーザーがサーバーのプログラムが動いている事を意識しないようにしたい) 何か良い仕掛けをアドバイスして頂けると助かります。。。 上記条件を満たせないとしてもどのようなやり方があるかを教えていただけるだけ でも参考になります。
>>552 数年前までは、デフォルトプロパティを省略すると動作が遅くなるから必ず書けと言われていた
今は有意な差がほとんどなくなったんで、指摘するとむしろ年寄り乙と言われる
そもそも計算速度を重視するんならC#とかもっと高速な言語を使うべきだし
>>559 昔からItemプロパティの場合、Valueは省略した方が速かったぞ?
Cellsで計ってみなよ。
事前バインドではほとんど差がなかったが。
>>561 多分559はOffice TANAKAあたりを鵜呑みにしてるんじゃね?
あれって計測は当時からいい加減だったからなぁ。
>>562 今高速化テクニック読んできた。
なるほどValueの省略は書き直されてはいるね。
しかし当時も今もCellsでは省略した方が速いんだよね。
いまどきCells主体のコード書く人はあまりいないけど。
コメントくれた皆、ありがと。
Rangeオブジェクトのプロパティの省略が
意図したとおりに動作するかどうかの明確な基準は不明で
質問した件については、どうもバグっぽい、ということようだな。
>>549 これが既知の問題だとは知らなかった。
アホゥな質問をしたことになるな、猛省!
●それから文言は正確な方がいいと思うので訂正しとく
簡単のために「Valueプロパティの省略」と書いたが
正確には「Rangeオブジェクトのプロパティの省略」
図が重なっていた場合のIF文を書いたのですがこれだとうまくいきません If ActiveSheet.Shapes("B").Top = ActiveSheet.Shapes("char").Top And ActiveSheet.Shapes("B").Left = ActiveSheet.Shapes("char").Left Then 図の移動は ActiveSheet.Shapes("char").Top = Cells(y, x).Top + 1 ActiveSheet.Shapes("char").Left = Cells(y, x).Left + 1 ActiveSheet.Shapes("B").Top = Cells(y2, x2).Top + 1 ActiveSheet.Shapes("B").Left = Cells(y2, x2).Left + 1 こうしています どうすればかさなっていることを判定できるでしょうか
ピボットテーブルのフィルタを複数選択可にしたリストボックスと連動させたいのですが、 時間がかかりすぎて困っています。 フィルタ項目のカテゴリは1000以上あり、最初の1つは基準になっているのでリストボックスには入れていません。 一つずつ変化させる場合の動作、全て表示させるボタン、基準を除いてすべて非表示にするボタンを それぞれ以下のように設定していますが、Listbox1OFFをクリックすると5分程度かかります。 もっと効率化できないものでしょうか。 Private Sub Listbox1_Change() Dim i As Integer With Worksheets("PIVOT").PivotTables("PIV").PivotFields("項目") For i = 0 To UserForm1.Listbox1.ListCount - 1 If .PivotItems(UserForm1.Listbox1.List(i)).Visible <> UserForm1.Listbox1.Selected(i) Then .PivotItems(UserForm1.Listbox1.List(i)).Visible = UserForm1.Listbox1.Selected(i) End If Next i End Sub Private Sub Listbox1ON_Click() Dim i As Integer For i = 0 To UserForm1.Listbox1.ListCount - 1 UserForm1.Listbox1.Selected(i) = 1 Next i Worksheets("PIVOT").PivotTables("PIV").PivotFields("項目").ClearAllFilters End Sub Private Sub Listbox1OFF_Click() Dim i As Integer For i = 0 To UserForm1.Listbox1.ListCount - 1 UserForm1.Listbox1.Selected(i) = 0 Next i Call Listbox1_Change End Sub
>>565 TopLeftCell, BottomRightCellを使ったらどうだ
Sub test()
Dim RngB As Range
Dim RngC As Range
With ActiveSheet
Set RngB = .Range(.Shapes("B").TopLeftCell, .Shapes("B").BottomRightCell)
Set RngC = .Range(.Shapes("char").TopLeftCell, .Shapes("char").BottomRightCell)
End With
If Not Intersect(RngB, RngC) Is Nothing Then
MsgBox "重なっとる"
Else
MsgBox "離れてとる"
End If
End Sub
●TopLeftCell, BottomRightCell, Intersectについては
必ず、ヘルプ参照のこと!
>>566 とりあえずScreenUpdatingをFalseにしてみたら?
569 :
566 :2011/01/10(月) 18:04:11
>>568 行数制限があるため省いていましたが、ScreenUpdating = Falseは既に入れています
>>566 そのまえにまず変数の使い方覚えた方がいいんじゃないの?
何度同じ記述が出てくるんだよ。
特にListbox1_Changeはひでーな。
1回クリックで5分もかかるレベルだと、小手先の修正じゃ改善は無理 根本的にロジックとアルゴリズムを考え直さないと 計算はもちろん手動にしてるよね?
570だが変数をうまく使えば速くなると言ってるわけじゃないからな。 コーディングの基本を勉強するのが先と言ってるだけ。
どこの処理で時間掛かってるか時間計ってみれば? .とりあえずPivotItems(UserForm1.Listbox1.List(i)).Visibleで判断しないで そこだけ別に保存しとけば? ピポッドテーブルなんて使った試しが無いから どれだけ時間がかかるかわからんが、そういうのって時間かかりそうじゃん。
574 :
566 :2011/01/10(月) 20:27:56
>>570 失礼いたしました。勉強します。
>>571 AutoCalculation = Falseは入れてみましたが、かかる時間が変わりませんでした。
自動計算とは無関係なようです。
>>573 前に、If判断自体を外したことがありますが、余計に時間がかかりました。
.PivotItems(UserForm1.Listbox1.List(i)).Visible = UserForm1.Listbox1.Selected(i)
の部分が時間を食うようです。
外したって↓みたいな感じじゃないよな? どっちにしろピボット止めない限りそれなりに時間かかるんじゃないか? 'If .PivotItems(UserForm1.Listbox1.List(i)).Visible <> UserForm1.Listbox1.Selected(i) Then .PivotItems(UserForm1.Listbox1.List(i)).Visible = UserForm1.Listbox1.Selected(i) 'End If
AutoCalculation=Falseってなんだ? 未宣言の変数にFalseを代入か? やっぱ変数の勉強が先だな。 オプションの「変数の宣言を強制する」にチェックつけろ。 それが上達の第一歩だ。
Application.Calculation = xlCalculationManual 入れてなかったって事か?単なる書き間違えか?
578 :
566 :2011/01/10(月) 20:48:34
Worksheet.EnableCalculationの間違いです。すみません。
579 :
566 :2011/01/10(月) 20:54:28
>>575 元々、おっしゃるとおりのIfが入っていない形で作成して、
あまりにも時間がかかるのでIfを入れたのが現状です。
Listbox1_Change ってイベントだよな? これ、コードでSelected変更したときに実行されてないか? だったらCall Listbox1_Change いらないと思うが
581 :
566 :2011/01/10(月) 21:56:00
>>580 投稿する際に省略してしまいましたが、イベントを実行するかどうかを制御するために、
FEnableEventsという変数を作成し、その中身を切り替えることによって、
Selectedの部分で呼び出されたChangeからはすぐ抜けるようにしています。
>>560 回答ありがとうございます。
早速試してみたいと思います!
583 :
566 :2011/01/11(火) 18:22:54
お騒がせしております。 改めてMSDNを見直していて.VisibleItems、.HiddenItemsというプロパティを発見し、 根本的な対策にはならないと思いますが、多少の負荷軽減を図ろうとしたのですが、 テストで書いたスクリプトが、ページフィールドの項目に対して予想通りの動作をしません。 Dim ThisItem As PivotItem With ActiveSheet.PivotTables("PIV").PivotFields("項目") .ClearAllFilters .PivotItems("A").Visible = False .PivotItems("B").Visible = False .PivotItems("C").Visible = False MsgBox "Visible: " & .VisibleItems.Count MsgBox "Hidden: " & .HiddenItems.Count For Each ThisItem In .VisibleItems MsgBox ThisItem & " is visible." Next ThisItem For Each ThisItem In .HiddenItems MsgBox ThisItem & " is hidden." Next ThisItem End With どのようにフィルタをかけていてもVisibleItems.Countが1でHiddenItems.Countが残りの選択肢数となり、 (All)がVisible、残りはHiddenという扱いになっています。 項目をページフィールドから行フィールドに移して実行すると希望通りの動作をするのですが、 何か方法を間違えているのでしょうか?
584 :
デフォルトの名無しさん :2011/01/11(火) 20:40:36
A列 0,-525 0,24525 4000,-525 上記座標データを使って新しい座標列を作っているが うまくいかない。XP sp3 + Excel2000。 C列 0,-425 -100,-625 100,-625 0,-425 0,24625 -10,024,425 ・・・・@ 10,024,425 0,24625 4000,-425 3900,-625 4100,-625 4000,-425 @は -100,24425 とならない。 修整法をおしえてください。
585 :
584 :2011/01/11(火) 20:41:25
Sub 計算() Dim chker As Range Dim dstn As Range Const dif = 100# Set chker = Cells(1,1).CurrentRegion Set dstn = chker.Item(1).Offset(0, 2) k = 1 With chker For i = 1 To .Count myArray = Split(.Item(i), ",") x = myArray(0): y = myArray(1) dstn.Offset(k, 0) = "": k = k + 1 dstn.Offset(k, 0) = CStr(x) + "," + CStr(y + dif): k = k + 1 dstn.Offset(k, 0) = CStr(x - dif) + "," + CStr(y - dif): k = k + 1 dstn.Offset(k, 0) = CStr(x + dif) + "," + CStr(y - dif): k = k + 1 dstn.Offset(k, 0) = CStr(x) + "," + CStr(y + dif): k = k + 1 Next i End With Set chker = Nothing Set dstn = Nothing End Sub
結果セル(C列)の表示形式を"文字列"にしとかないと拙いだらう。 手動で設定した後、実行する、 または、コードでやるなら先頭に下記のどれかひとつを追加 dstn.EntireColumn.NumberFormatLocal = "@" Range("C:C").NumberFormatLocal = "@" Columns(3).NumberFormatLocal = "@" Range("C1").EntireColumn.NumberFormatLocal = "@"
587 :
584 :2011/01/11(火) 22:36:59
Excel:2007 OS:XP Chr関数について教えて下さい〜 cells(1,1)に今"う"という1文字が入っているとして MsgBox AscW(Cells(1, 1)) とすると 12358 と表示されます。んで、次に MsgBox Chr(AscW(Cells(1, 1))) とすると 0 となってしまうんですけど、元の文字(この場合は"う")が返ってきて欲しい んですけど…
ExelのVBAでおみくじに画像を貼り付けたいのですが… 「大吉」「小吉」などごとに様々な画像が出るようにしたいのです よろしければ教えてくださいませんか?
またすごい質問が来たな
>>588 Shift JISでやりたいなら Chr(Asc(r
Unicodeでやりたいなら ChrW(AscW(r
長くなりそうだな
>>589 まず画像だすのはおいといて、おみくじ本体部分は完成してるのか?
>>593 MsgBoxでおみくじ本体は作っているのですが・・・
おみくじの画像表示するだけだったら、 あらかじめ画像をシートに貼り付けておいて 表示するときにシートをVBAで切り替えちゃえば?
じゃあ画像だす方法を決めろ
MsgBoxに任意の画像出すのは難しい。それっぽいフォームを自作するとか
>>595 のようにするとか
Excel2002、OSはWinXP(SP3)を使用しています。 エクセルからMSCommや他モジュール(EasyComm等)を使ってシリアル通信をするマクロを 組もうとしています。 Asciiの送信は特に問題は無いのですが、コマンドに^A(ctrl+A)というのがあり、 これの送信方法がわからずに困っています。 ^A(ctrl+A)を送信するとき、送信バッファにはどう入れればよいのでしょうか?
600 :
599 :2011/01/12(水) 21:40:13
>>598 ゴメン
文字コードでダメならキーコードで
>>566 ボトルネックをぐぐれ。
・・・したいことは分かるが、めんどい。
それを完全に再現出来るxlsあげれば暇な時に調べてやってもよい。
>>589 めんどい。BitBltとLoadPicture調べろ。
IPictureDispとかもあるが、さらにめんどい。
603 :
566 :2011/01/13(木) 20:01:56
開くことすらできんぜよ
rarかよw
鯖busyで落ちない
607 :
566 :2011/01/13(木) 22:02:35
>>607 2007? 2010?
環境くらい書いてくれ。
609 :
566 :2011/01/14(金) 20:32:49
>>608 何故か書いたつもりでおりました。ごめんなさい。2007です。
行の削除についてなんですけど、、例えば 2行目から4行目を消すなら Range("2:4").Delete ってしますよね。 これを変数を使ってn行から n+100行を削除したいんですけど、どの様にすればよろしいのでしょ
>>610 Rows(n).Resize(100+1).Delete
すなわち
Rows(n).Resize(101).Delete
少し不細工な書き方なら
Range(Rows(n),Rows(n+100)).Delete
も一つ不細工な書き方もあったか Range(n & ":" & n + 100).Delete
Resizeっての、初めて知りました。ありがと!
>>566 Pivotなど使ったことないんでなんだが
全てクリアーなんだからフラグでも使ってChangeのForを飛ばしたらどうだらう
で、メンテ部分だけ。。
--------------------------------
Private Flag As Boolean
------------------------------------
Private Sub Section_Change()
With Worksheets("PIVOT").PivotTables("TABLE").PivotFields("部署")
If Flag Then
Flag = False
i=Form.Section.ListCount - 1
Else
For i = 0 To Form.Section.ListCount - 2
If .PivotItems(FS.List(i)).Visible <> FS.Selected(i) Then
.PivotItems(FS.List(i)).Visible = FS.Selected(i)
End If
Next i
End If
.PivotItems("(blank)").Visible = FS.Selected(i)
End With
End Sub
--------------------------------
Private Sub SectionOFF_Click()
Flag = True '▼必要な場所(例えば先頭)
End sub
---------------------------
それにしても何て寒いんだぁー、、底冷えの鹿児島より
>566 確認した。 使用詳細がわからんので、使える方法で。 (1) Section_Change For文のToで指定してるところをローカル変数にする Dim iIndex As Long iIndex = Form.Section.ListCount - 2 For i = 0 To iIndex (2) 自動計算をやめる 停止 Application.Calculation = xlCalculationManual 再開 Application.Calculation = xlCalculationAutomatic (3) SectionOFF_Click Section_Changeをやめる。 Worksheets("PIVOT").PivotTables("TABLE").ClearTableでクリアしたあとで UserForm_InitializeやItemSet等の中から必要な処理を追加。 あとは、ステータスバーの「処理中」を、細かく処理状況がわかるようにすると 長く待っているストレスが軽減される(気分的に)
>>566 次に重い If .PivotItems(UserForm1.Listbox1.List(i)).Visible <> UserForm1.Listbox1.Selected(i) Then
一番重い→ .PivotItems(UserForm1.Listbox1.List(i)).Visible = UserForm1.Listbox1.Selected(i)
だからPivotItems(UserForm1.Listbox1.List(i)).Visibleを変数に変える様前言ったんだけど
結局どうなったの?やって大して変わらなかったの?
ピポッドテーブル使う設計自体が良くないと思うんだけど変えるのはまずいの??
>>616 俺も変数使えといったけど、たしして変わらんと思うなぁ。
それにPivotItems(UserForm1.Listbox1.List(i)).Visibleは変数にできないんじゃない?
上は取得で下は設定だし。
もちろんUserForm1.Listbox1.List(i)は変数にできるが、これの取得にはそれほど時間
かかってないと思う。
ところでみんなに聞きたいんだがSection_Changeの変数FSって何型が適当?
Object型なら変数使わないで
If .PivotItems(Section.List(i)).Visible <> Section.Selected(i) Then
.PivotItems(Section.List(i)).Visible = Section.Selected(i)
なんてやった方がまだいいと思うんだが、変数にするときの型が分からん。
ListBox型だと思ったら型不一致になる。
>>617 Dim FS As MSForms.ListBox
意味取り違えてたら勘弁!
619 :
566 :2011/01/15(土) 15:25:18
皆様レスありがとうございます。
>>614 For文をとばしてしまうと、実際にフィルタが変更されないと思うのですが……
>>615 (1)、(2)はそれぞれTimerで計測してみましたが変化がありませんでした。
(3)はテーブルをクリアした状態でフィルタを変更しろということでしょうか。
試してみます。
>>616 .Visibleまで含めて変数に入れるということが発想に浮かんでおりませんでした。
しかし、PVという変数をObjectで宣言しておいてSet PV = .PivotItem(FS.List(i)).Visibleとやると、
型が違うというエラーになります。
なお、元々ピボットテーブルでやっているものに補助で操作パネルをつけるという経緯なので、
ピボットをやめるというのは難しいです。
620 :
566 :2011/01/15(土) 15:57:30
>>615 SectionOFF_Clickの最初にWorksheets("PIVOT").PivotTables("TABLE").ClearTableを入れ、
末尾にWorksheets("PIVOT").PivotTables("TABLE").PivotFields("部署").Orientation = xlPageFieldと
Call ItemSetを入れると、速度が劇的に改善されました。
十数秒はかかりますが、今までに比べれば許容範囲内です。
早速本体の修正にとりかかります。
ありがとうございました。
621 :
617 :2011/01/15(土) 16:51:05
>>618 あ、そうかMsFormsだったか。
>>618 VisibleプロパティってTrueかFalseしか返さないだろ?
エラーになるのは当然だな。
622 :
617 :2011/01/15(土) 16:52:26
アンカー、ミスったわ
623 :
566 :2011/01/15(土) 17:59:12
>>621 PVという関数があるようでしたので、後に別の変数名に変えて試していますが、
Booleanにしても、Dimで型を指定しなくてもエラーになります。
単純にイコールで代入するということならば、フィルタの変更には使えないので、
iが変わるごとに1度ずつしか参照されず、代入分が余計に負荷になると思うのですが、
認識が誤っているのでしょうか。
もうね、ピボットテーブルやめて、生データ自分で拾って表を作り直した方が早いんじゃない?
625 :
617 :2011/01/15(土) 19:21:13
>823
.Visibleまで含めて変数に入れてもしょうがないんだよ。
>>617 に理由書いてるだろ?
>>824 おれもそう思う。
626 :
566 :2011/01/15(土) 19:57:56
>>625 元々、
If .PivotItems(UserForm1.Listbox1.List(i)).Visible <> UserForm1.Listbox1.Selected(i) Then
.PivotItems(UserForm1.Listbox1.List(i)).Visible = UserForm1.Listbox1.Selected(i)
End If
としていたのに対して、変数を使うようにというアドバイスをいただいたと認識しているのですが、
結論としては、UserForm1.Listbox1をMSForms.ListBox型の変数に入れる以外には、
ここで変数を使うメリットはないということですね。
となると
>>617 の方の意図がよく分からなくなりますが……
ピボットをやめた方がいいというのは重々承知しておりますが、
いくつか有効なアドバイスもいただけましたので何とか使えるものになりそうです。
ということで、これにて失礼させていただきます。皆様ありがとうございました。
628 :
デフォルトの名無しさん :2011/01/16(日) 16:15:02
最近学び始めたど素人です。 セルの文字列値を読み取って、処理したいのですが、 moji = LEFT(A1,1) のように書けば、A1のセルの左端1文字目をmojiに収納することができるのでしょうか?
その書き方だと、A1(という変数)の左1文字 A1のセルなら、moji=LEFT(Range("A1"),1) だな Rangeの前に、どのシートなのか書いといた方がいい Rangeの後に、中身の文字だってのも書いといた方がいいかもしれん Rangeの代わりにCellsってのもあるけど、最近つかわれてないなぁ
630 :
デフォルトの名無しさん :2011/01/16(日) 19:21:22
>>629 なるほど。とても分かりやすい解説ありがとうございます。
早速行ってみます。
Cells表現って使われなくなってきたん? VBA使うなら圧倒的にCellsの方が可読性が高いと思うんだけど。
自分もCells派だ。
633 :
デフォルトの名無しさん :2011/01/16(日) 23:55:15
Rangeのいいところ:名前でセルを指定できる シートが違ってセルの位置が変わっても名前付きセルなら同じコードで対応できる つーか、Range(\\\"A1\\\")みたいにマジックナンバーを使うんじゃねえ!
634 :
617 :2011/01/17(月) 09:48:14
ループの中で使うならRangeもCellsもどちらも駄目だな。 With Worksheets("Sheet1") For i = 1 To *** Step 2 .Cells(i,1).Value = *** Next End With とか With Worksheets("Sheet1") For i = 1 To *** Step 2 .Range("A"& i).Value = *** Next End With こんなのはどちらもダメだな。 いったんRange型の変数にセットしないとね Set c = Worksheets("Sheet1")Range("A:A") 'Worksheets("Sheet1")Cells.Resize(,1)などでもいい For i = 1 To *** Step 2 c(i).Value = *** Next みたいな感じ。
Cellsしか使わないなぁ
636 :
デフォルトの名無しさん :2011/01/17(月) 12:40:48
XP SP3 + Excel2000 シートを3枚選択して縮小をかけるマクロで、@のArrayを十何枚ものシートにも 対応できるように簡単にできないでしょうか? Sub zoom85() Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Select @ Sheets("Sheet1").Activate ActiveWindow.Zoom = 85 Sheets("Sheet3").Select End Sub
VBAの処理でセルの値をクリアして、その結果、 specialcells(xlcelltypelastcell )で取得できる範囲を更新する(縮める)には、 一度ブックを保存するしかないのでしょうか。
639 :
初心者 :2011/01/17(月) 17:25:07
オブジェクト(角丸四角形)とコネクターがツリー構造でつながっていて そのツリー構造をセルに出力したいんですけど。。。。 セルに文字で上位、下位情報を出力したいです。オブジェクトの上位下位を考える際に座標位置で探るのかなぁと思ったんですが、どうすればいいのかわからなくて。。。。 いまいち書き方がわかりませんでした。教えてください!! 例 どうぶつ ∧ いぬ ねこ | 柴犬 みたいなツリーに対して どうぶつ いぬ どうぶつ ねこ いね 柴犬 こんな感じで出力したいです。^^
640 :
デフォルトの名無しさん :2011/01/17(月) 20:25:19
エクセル2003のマクロを2010で使用しようとしたら、エラーメッセージが出ました。 なにか変換ソフトがあるのでしょうか?
641 :
636 :2011/01/17(月) 20:36:05
>>637 >>Worksheets.Select ' --全てのシート
arrayに引きずられていました。
ありがとうございます。
>640 最低でも、エラー内容と、エラー発生した行の内容くらい書かないと、誰も答えてくれないでしょ。 エラーがExcelのバージョン違いによるものなのか、PC環境の違いによるものなのかもわかりません。
643 :
デフォルトの名無しさん :2011/01/17(月) 20:47:41
>>642 ただ単にボタンを押すと時間を取り込むものなのですが、
「このブックでマクロが使用できないか、全てのマクロが無効になっています」
と表示されます。セキュリティでマクロ有効にしたのですが、無理です。
>>643 セキュリティセンターの設定で信頼できる場所にエクセルファイルの置いてあるフォルダを追加
645 :
sage :2011/01/18(火) 19:29:54
お邪魔します、VBA初心者です。 現在、1時間に観測したデータ10個を平均して1個にし、 次に1時間後のデータを同じく平均して1個にするのを約1か月分繰り返す計算を考えています。 平均の出し方や同じ計算を繰り返す方法は大体分かったのですが、 次の行に行かず、2時の計算が終了したら3時の計算に移りたいんです。 なので、次に計算する範囲を先読みして指定して繰り返すのにいい方法はありませんか?
>645 計算対象のデータがどういう風にシート上に配置されているのかわからないので、 回答したくても、できません。
648 :
645 :2011/01/18(火) 21:21:50
>646 説明不足でした、すみません。 Aに日時 Bに観測値 Aは同じ日時が10個縦に並んで連続してる状態です。 たとえばCに1時間ごとの日時を並べて、それに合わせて平均値を詰めて行きたいです。 A B C D 1/1/00:00 10 1/1/00:00 0時の平均 1/1/00:00 12 1/1/01:00 1時の平均 1/1/00:00 14 1/1/02:00 2時の平均 : : 1/1/01:00 20 1/1/01:00 13 >647 そこから次の時間の平均計算に移動する方法をお聞きしたいです。
>>648 D1=AVERAGE(B1:B10)
D2=AVERAGE(B11:B20)
D3=AVERAGE(B21:B30)
>>648 無理してVBA使わないでピボットテーブル使えば?
>>648 Dim b As Long, d As Long, i As Long, cnt As Long, ttl As Double
d = Cells(60000, 4).End(xlUp).Row
If d <= 1 Then
b = 1
Else
b = 10 * (d - 1) + 1
End If
Do While Cells(b, 2) <> ""
cnt = 0
ttl = 0#
For i = 0 To 9
If Cells(b + i, 2).Value <> "" Then
ttl = ttl + CDbl(Trim(Cells(b + i, 2).Value))
cnt = cnt + 1
Else
Exit For
End If
Next i
If cnt < 9 Then
Exit Do
Else
Cells(d, 4).Value = ttl / 10
d = d + 1
b = b + i
End If
Loop
私も649、650に賛成です。
質問者のレベルではピボットは無理かも。。
>>649 でいけばいいと思うが。。。
Sub Test()
Dim R As Long
Dim Lst As Long
For R = 1 To Cells(Rows.Count, 1).End(xlUp).Row Step 10
Lst = Lst + 1
Cells(Lst, 3) = Cells(R, 1).Value
Cells(Lst, 4) = WorksheetFunction.Average(Cells(R, 2).Resize(10))
Next R
End Sub
653 :
645 :2011/01/19(水) 12:00:38
返答ありがとうございます。 とりあえず皆さんのを参考にもう一度チャレンジしてみます!
OLEObjectのTextBoxでBackStyleを0に設定しました 手動でテキストを入力するとBackStyleの設定は0のままなのに、透明ではなくなってしまいます 入力しなくてもクリックしただけで透明でなくなってしまったり、意図しないタイミングでまた透明になったりします マクロからObject.Textで文字列を入力すると透明のままです Objectのプロパティの設定だけで絶対に透明を維持する事はできないのでしょうか?
655 :
デフォルトの名無しさん :2011/01/19(水) 17:10:06
WorksheetFunction について質問します。 "Run-time error'1004': Unable to get the Atan2 property of the WorksheetFunction class" が出るようになりました。 Atan2が動いているモヂュールの入ったファイルを別保存していじっていたら エラーがでました。元ファイルのモヂュールは動きます。 なにか示唆ありますでしょうか? XP SP3 + Excel2000
アドインが選択されていないと思われ
>>655 ワークシート関数のエラーは、シート上では#NUM!とか#VALUE!とか場合に応じて色々出るけど、
VBAから呼び出した場合はほとんどみんな同じエラー1004になるから原因が追及しにくい。
Atan2のパラメータが両方とも0になってないかチェックしてみ
あと、そのExcelって英語版?
vbaは思ったより奥が深くて飽きないな。
それはvbaの深さじゃない。に 1000点。オッズは256倍
なんの深さと言えば正しいの?
661 :
655 :2011/01/20(木) 12:22:06
>>657 x,y項の計算結果が ともに先頭で0になっていました。英語版です。
回避ルチンを挿入しました。
ありがとうございます。
複数選択を可能にしたリストボックスをUserForm_Initializeで全選択させておいて タブでフォーカスを移してカーソルキーでリスト内を移動しようとすると 1回だけChangeイベントが発生します。 また、リストボックスをクリックした場合にもChangeイベントだけ生じて リストの選択に変化がないことがあります。これは法則がよく分かりません。 回避方法はあるでしょうか?
663 :
デフォルトの名無しさん :2011/01/20(木) 23:57:56
VBA始めたばかりの超初心者です。 2つご教授願います。 1つめは、A列に400件郵便番号が入っていて そのA列に1112222とハイフン抜きになっている文字列に関して、 全て111-2222とハイフンを付けたいのですが どうマクロ組んだらよろしいでしょうか 2つ目はB列のセル内の左端にある スペースを消して左に文字列を詰めたい場合 [ 12345]→[12345] どうマクロを組んだらよろしいでしょうか。 よろしくお願い致します。
openステートメントで既に開いているファイルをlock read writeで開こうとすると エラーが出るのは開かれててまともな排他制御できらいからエラーだよんって 解釈でいい?
>>663 Sub 郵便番号修正()
Range("A1:A400").NumberFormatLocal = "000-0000"
End Sub
Sub 左詰め()
Range("B1:B400").NumberFormatLocal = "@"
For r = 1 To 400
Cells(r, 2) = LTrim(Cells(r, 2))
Next
End Sub
愛の深さ 欲の深さ 業の深さ
668 :
デフォルトの名無しさん :2011/01/22(土) 01:31:07
Excelシートで列を指定してソートってVBAだと一回に3つまでしか指定できないんですか?
Range.Sortメソッドに頼るならそうなるな。
>>668 Excel2007以降なら何個でもいける。
ただし2003までのソートと同じ書き方では出来ないけどな。
sortはpythonと同じようにかければメチャ楽なのになぁ。
672 :
デフォルトの名無しさん :2011/01/22(土) 17:50:02
PERSONAL.XLSに登録された複数のモジュールを同時にエクスポート&解放したいのですが、 どうすれば良いですか? 一つ一つクリックして、右クリックで解放を選ぶのは非常に面倒です。 検索などしてもどうやっても方法等書かれたページが見つかりません。 どなたか教えて下さい。
>>672 マウスやキーボード操作で一括指定する方法はない
まとめてやるにはエクスポートするVBAを作るしかないと思う
674 :
デフォルトの名無しさん :2011/01/22(土) 20:24:53
>>673 むぐう、どなたか親切な方、全エクスポート&解放するVBAを教えて下さい。
マクロで作ろうと思っても、VBA上の操作で記録出来ないじゃないですか?
どうやってやれば良いのですか?
>>674 VBAから標準モジュールをエクスポートするためには色々と設定が必要。
まず参照設定を開いて「Microsoft Visual Basic for Applications Extensibility」にチェックを入れる
次にセキュリティセンターを開いて「Visual Basct プロジェクトへのアクセスを信頼する」にチェックを入れる
ここまで準備して、やっとVBProjectオブジェクトが使えるようになる
このオブジェクトでインポート、エクスポート、その他色々な機能が使えるようになる
VBProjectはけっこう強力、かつ危険なオブジェクトなので、使い方を自力で調べられるレベルでなければ
使わない方がいい。
>>672 解放の手順を慎重に調べてuwscとか使えば?
たぶん
コンテキストメニュー → R (解放) → Enter (エクスポート) → Enter (ファイル名決定)
の繰り返しあたりでできるんじゃないかと思う
こういう場合、繰り返しの回数は手動設定が一番簡単
677 :
デフォルトの名無しさん :2011/01/23(日) 06:57:39
Excel VBAで、フォームボタンを押したらWebページ保存するようなの作ったんですが、 (当然ですが)ボタンもhtmlに保存されてしまいます。 表示しないテクニック(?)はないでしょうか。 イメージ的にはExcelで作ったテーブルをそのままhtmlにしてWebに公開したいような感じです。
選択範囲を保存にして、ボタンを選択範囲外にするとか?
フォームは検証が面倒なので、サンプルうpしたほうが解決しやすい
フォームじゃないとだめ? ツールバーにボタンを作るとか、ショートカットキーとか いろいろ方法はあると思うけど 保存の直前に一時的にフォームを非表示にするとどうなるだろう
>>678 ,
>>680 そういう一般的なテクがあるのかなーと思いまして質問しました。
>>679 ボタンの中身はSaveAsするだけの単純なものです。
あとファイル名とかキャンセル時処理とかごにょごにょ。
>>682 Excel 2003 SP3
ActiveWorkbook.SaveAs Filename:="index.html", FileFormat:=xlHtml ・・みたいな感じです。
試してみたけど、Visible = Falseにしてもデータ自体は表示されないだけで保存されちゃうんだね 保存されたhtmlを直接編集して不要な部分を手作業で削除するとか、新規ブックに必要なデータだけをコピーしてから保存するしかないかも お手軽にやるならhtmlとxmlをテキストエディタ編集、VBAだけで全自動でやるなら新規ブックで保存かな
なるほどありがとう。 あんまり複雑にしても他の人がメンテ不可能になるし、結局やることは「名前をつけて保存」押すのと同じですから、困ったもんですね・・ でも大変参考になりました。
>>685 フォームじゃなくてツールバーにしたら?
ボタンの登録や削除もVBAからできるよ
KEYの重複チェックってどうやってするのが 効率良いですか? 例えばA列に年、B列に組、C列に出席番号、D列に名前 だとして、全学年6万人ぐらいとかのパターンです。 ループでrow方向にゴリゴリ回すとちょっと遅い様な気がして。 1列だけならfindが早い気がするんですが
>>687 keyってのはユニークな値の入ったフィールドのことだから、その用法は間違い
調べたいのはレコードの重複?
だとしたら一番単純明快なのは全部1つに連結した物を作業列に入れる
>>688 そうですレコードの重複。作業列って事はE列を隠しセルにして
関数で全部くっつけるとかですか?
さすがに足し合わせは初心者過ぎるだろ。 調べたいキーのみSELECT COUNT(*) ・・・ GROUP BY KEY1, KEY2, ・・ でいいだろ
>>689 関数でもいいけど普通は数式で連結
E1=A1&B1&C1&D1
とか入れておく
>>690 まあSQLを使った方が早いわな
でもここはExcelスレだから
SQLだと編集中のレコードがチェック出来なくないですか?
何か勘違いしてるんでしょうか私が
>>691 ああ、すいません関数じゃなくて数式ですね
簡単な方法でできるのにわざわざ難しくて面倒な方法を採用する
696 :
デフォルトの名無しさん :2011/01/25(火) 21:55:38
質問です ツール→マクロでマクロの選択画面がでてきますよね。 あれに登録しているSubプロシージャが出てきますけど、出さなくする方法ってありますか? 今は出したくない奴については無理やりダミーの引数与えてださなくしているんですけど、そうすると 単独では実行できなくなるし、どうしたものかなぁ…っと思ってんですけど。 セキュリティ云々なんて大層なことではなく、あんまり一杯出てくると紛らわしいってのが理由なんですけどね
>>694 私としても簡単な方がいいので、そういう方法があるのなら教えてください
>>695 でくしょなりは登録する時の全件チェックではやってるんですが
単体チェック(全体チェックでセルの色を変えてるのでそれを戻すチェックです)
だと一回全部登録しないと駄目だから
結局ループするのと大して変わらないんじゃないかと思って使ってないです。
dictionaryに一気に登録する方法があったりするのでしょうか?
>>696 目的のプロシージャを探すのが面倒だっていうのなら、名前の先頭にa_を付ければ
リストの先頭に出てくるようになるよ
ダミーの引数を書くより簡単
Sub test()
↓
Sub a_test()
>>696 privateにするか、出したくないプロシージャをまとめて
ひとつのモジュールに入れるとか。
確かモジュール丸ごと出さなくするのあったはず
>>698 60000件ぐらいたいしたことないでしょ
702 :
696 :2011/01/25(火) 22:30:22
>>699 確かにそうすると先頭に来るから判りやすいっすね
>>700 privateにすると出てこなくなるの初めて知った w
有難うです m(_ _)m
703 :
デフォルトの名無しさん :2011/01/25(火) 23:10:15
>>703 仕様に不明な部分がある
00分ちょうどに出入りがあった場合は台数をどちらにカウントするのか?
分類する時、入出場時間が指定期間外にまたがった車はどう処理するのか?
ユーザーインターフェースや出力はどうするのか?
あと、曜日の列は冗長だな
00分に駐車場内にいる=駐車している、でいいんじゃね? つかこれ、VBAじゃなくて関数使ってワークシートで計算する問題じゃね?
706 :
デフォルトの名無しさん :2011/01/25(火) 23:36:16
ワークシートでやるのか それでもどうやるんだろうな
ここに書かれたってことはVBAの問題でしょ 時刻がソートされてないからワークシートじゃ効率悪すぎる
>>698 >単体チェック(全体チェックでセルの色を変えてるのでそれを戻すチェックです)
xl2007以上を使ってるんなら、色でフィルター掛ける
それ以外のバージョンなら、色を付けると同時に別セルにフラグでも立てておき、そのフラグでフィルターをかける
その後、SpecialCellsで処理するってのはどうよ
>>707 >時刻がソートされてないからワークシートじゃ効率悪すぎる
問題はみてないが、
ソートがされてないのが効率が悪いと思うなら
ソートして、処理後に戻せばいいだけじゃないのか
VBAで処理するデータはふつうソートなんかされてないぞぃ
もち、ソートもVBAで、
>>709 いやだからVBAの問題でしょって言ってるんだけど
これC/C++宿題スレで見たことあるぞ
wwwwww
きっと宿題ミスったんだなw どうみてもワークシートでやるレベルのそれにしか見えないけど
>>710 確かにそう言っとるな
I apologize....
ITではなくて、IT以外の一般企業に就職にするにあたって、VBAはどんな感じでアピールになりますか?
>>715 雑用が増えるだけだからアピールしないほうがよい。
そしてなぜか全くVBAと関係ない事を頼まれる
「VBAができます」じゃなくて、「VBAを使ってこれこれこういうことができます(やりました)」でないと アピールポイントにはならないよ
手っ取り早く、実際にプログラミングした作品をつくって提出してみせるのどうよ?
>>703 ダウンロードできないので問題が見えないが、時刻区間ごとの個数ならSUMPRODUCT使うやつはアホだな。
関数ならFREQUENCY、一般的にはピボットテーブルでグループ化だな。
VBAならみんなが言ってるようにソートして求めるんだろう。
関数でSUMIFはだめだ。
もしかして駐車場の入出時刻がそれぞれあって、ある時刻区間ごとのに何台駐車しているかっていう問題か? だったら上は違うか。
Excel2007 A1に "test" という文字列が入っています ※ダブルクォーテーションの"もついています この半角ダブルクォーテーション " を全角のダブルクォーテーション ” に置き換えるにはどうすればいいのでしょう? Cells(1, 3) = Replace(Cells(1, 1), """",""") とすると 引数は省略できません とコンパイルエラーになります おまけに全角の”が自動的に半角の"におきかえられてしまうし…
724 :
723 :2011/01/27(木) 10:17:29
事故解決 x = Cells(1, 1) Cells(1, 3) = Replace(x, Chr(34), Chr((-32408))) めんどくさい!!!!!!!!!!!!!!!! スレ汚しすまんです
確かに勝手に直されるのは気に入らない 別解だが Cells(1, 3) = Replace(Cells(1, 1), """", StrConv("""", vbWide))
727 :
sage :2011/01/28(金) 12:37:51
誰か教えて下さい エクセル2007で埋め込みグラフを描くマクロを使ってるんですが最近やけに重いです 最初はサクサク動いてたのに、グラフを見やすくするために、セルの背景色とかセルの列の幅を変えただけで応答なしになります グラフは削除マクロで消しているのでオブジェクトが大量発生してるのではないと思うんですが、、、 ---削除マクロ--- Sub ChartsDelete() With ActiveSheet.ChartObjects If .Count > 0 Then Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True End If End With End Sub ---削除マクロ--- エクセルの書式変えただけでマクロが動かなくなることってあるんですか?
昔納品した会社から、そういう話は聞いた Excelのバージョンアップしたら、うち以外のも グラフが軒並み遅くなったとは言ってたな 結局、前のバージョンで動かすことにしたようだが 原因は調べてないので判りません
たしかに新しいExcelはグラフ重いよね。
730 :
727 :2011/01/29(土) 08:57:59
マジデスカ 埋め込みじゃなくてグラフシートでもダメなのかな・・・・ そこまではわかんないですかね?
731 :
デフォルトの名無しさん :2011/01/29(土) 14:04:16
VBA及びジャンプ機能を使わずに、 数式の入っているセル と、 値(数字)が直接入力されているセル を区別する方法を教えてちょ。 関数を使う方法でも条件付書式を使う方法でも可。 よろしこ
733 :
731 :2011/01/29(土) 15:49:32
そこレベル低いんだもん
>>731 A列 B列
1 =A1*10
3 =A1+B1
20 5
8 =SUM(A1:A3)
Ctrl+F3
名前:test
参照範囲:=GET.CELL(6,!B1)
C1セルに =IF(LEFT(test,1)="=","式","式じゃない")
735 :
731 :2011/01/29(土) 22:56:50
教えてください。 Excel2003, Win7, 64bitです。 1. VBAでのヘルプ VBA Editorで、HELPを開いてキーワードで検索して、4つとか見つかるのですが、 その見つかった結果をクリックしても、何の窓も出ないし、表示もされません。 どのようにすれば表示するのでしょうか? 2. Module名の変更 同じくVBAエディタで、プロジェクトウインドウ?(左側の窓)で右clockして、 挿入、標準モジュール、として「Module1」という名前で新しいモジュールが出来ます。 この名前を Module1から、自分の好きな名前に変えたいのですが、 どのようにして行うのでしょうか? Excel98のときは、確か右クリックか何かで 変えられたと思うのですが。 すみません。よろしくお願いします。
>>736 1. EXCEL2000の頃からそうだよね。解決法は知らん
2. モジュール選んでF4押してみる
Excelのヘルプのやる気の無さは異常。 ユーザーに読ませる気無いだろ、あれ。
ありがとうございました。 1. そうなのですか? 何のためのヘルプなのか、という感じですね。 2. できました。まどがもう一つあるんですね。忘れていました。 ありがとうございました。 もう一つ困っていることを教えてもらえないでしょうか? モジュール内に、Sub openbook()で、Public変数の代入(初期化)をしました。 その後、ボタンのイベントで別モジュールを起動して、その初期化された変数を使って 処理しようと、変数を見ると、""(null)になったままで、初期化の数値が入っていません。 何か私は勘違いをしているでしょうか。 -----------------------------------------別Module----------- Public I as Integer Public S as String Sub Openbook() ' Bookを開いたとき1度だけ実行 I=1 ' 1が入るはず S="E" ' Eが入るはず MsgBox " OPEN " ' このメッセージBOXは実行されます。 End sub -----------------------------------------別Module----------- Dim I as integer Dim S as String Private Sub B_click() if( I=1 ) then ' ところがI="" Elseif( I=2 ) then ・・・・ if( S="U" ) then 'ところがS="" Elseif( S="E" ) then ・・・・ End sub
別モジュールを、例えばModule1とModule2とするなら、 Module1.IとModule1.Sを初期化した後で、 Module2.IとModule2.Sを参照しようとしているようなものだな。 初期化されていなくて当然、としか。
>>739 2番目のモジュールの先頭のDimは不要
>>740 ありがとうございます。
>初期化されていなくて当然、としか。
なぜなのでしょうか? 実行順序は、Module1(Openbook側)を先にやって・・・・
もしかして、Module1でDim宣言をしないといけないのでしょうか?
プロジェクト内ならどこでもいいわけではなくて。ちょっとやってみます。
>>741 ありがとうございます。やってみます。
>>742 >Type ブロック外では無効なステートメントです。
と言われてしまいました。
ヘルプを見るとDimを付けるならいいけど・・・・みたいなことが書いてあります。
モジュールは1つのオブジェクトだよ
>>744 >モジュールは1つのオブジェクトだよ
オブジェクトの意味がわかりません。すみません。
Dim A as IntegerでOKなのに、
Publicだと
Public Dim A as Integerはエラーで
Public A as IntegerだとOK。
「なんでDim無しでいいの? PublicとDimは意味がちゃうやん」と、予想が全く当たりません。
マイコンのCや、FPGAのVerilogは、それほど違和感なく受け入れられるのですが、
VBAになると途端に頭の中が沸騰してしまいます。なんか泣けてきました。
今日は帰ります。ありがとうございました。
>>739 OpenBookがあるモジュールの変数IとSは、確かにどこからもアクセス可能になってるよ
だけど、参照元のモジュールにも同じ名前の変数をグローバル宣言してるからそっちが優先されてるだけ
B_clickがあるモジュールにグローバルなDim宣言があるので、
そのモジュール内から単にIと呼んだ時はこっちの事だと解釈される。
その状態でOpenBook側のグローバル変数を呼ぶには、そのモジュール名.Iで呼ばないと。
つーか普段はモジュール名を省略して記述してるって事を理解したらわかるんじゃね?
>>745 >「なんでDim無しでいいの? 」
たぶんね、大昔ね、Publicが初めて登場した時に変数専用の宣言文だったのが原因なんだよ
Dimをグローバルな所に置けたらいいんじゃね?
↓
お、それ頂き!
でもこれ慣れるまでは勘違いでバグの元になりそうだな…
↓
じゃあ、宣言文ですぐ分かるようDimじゃなくPublicって事で
↓
お、それ頂き! 今度からグローバルな変数の宣言文はPublicな!
というわけ…いや、まるっきり推測だけど。
BorderStyleって、なんか変な状態になったりしない? VBAで罫線をクリアするコード書いてみたんだけど、 まったく設定されていないはずなのに、罫線がそこだけ表示されないんだ WindowのDisplayGridlinesはTrueなのにおかしなセルだけFalseになってるような不思議な状態。真っ白。 ウォッチウインドウでまともなセルとBordersの中身を見比べたけど、 一切違いがないのですよね…なんだろうこれ… ExcelのUIで書式を見比べても見た目同じ、 でもその画面のクリアを押すと直る、つまりClearFormatじゃないと直せないって事か。 いちど罫線を設定してから再びStyleNoneを設定する事でも直るっぽいけど、これバグなのかしら…
>>748 仕様という名のなんとやらだった気がする
ある状態になると未設定状態に戻すことが出来なくなり、
セルの消去かフォーマットのクリアしか手が無くなる、とかうろ覚え
罫線は鬼門だよな
制御がやたらメンドい
俺は出来る限り罫線に触れぬようコーディングしてるわw
変な動きつーか、内部的にどう動いてるのか把握しにくくいんだよな
結果的になにがどーなってるのかわかんなくなる
いつのまにかUsedRangeがシート全域に及んでたりして速度低下とかな
750 :
745 :2011/01/30(日) 13:31:59
>>741 >2番目のモジュールの先頭のDimは不要
この意味がわかりました。Dimの行全体が不要ということですね。ありがとう。
>>746 >
ttp://niyaniya.info/pic/img/11556.jpg とても具体的な回答を、大変ありがとうございました。そういうことだったのですね。
やってみたら、あっさりとmodule間のやりとりができました。お手数をおかけしました。すみませんでした。
>>747 >そのモジュール名.Iで呼ばないと。
わかりやすい説明を、ありがとうございます。フルパスで指示しないといけない、みたいな感じです。よくわかりました。今回は私の勉強不足でした。
>というわけ…いや、まるっきり推測だけど。
いや、当たってると思います。
私も頭が固い(柔軟性がない)ですが、VBAの記述は、予想がしにくいなぁと思います。
ソフトやるときって「あれがそういうことなら、この場合はこう書けばいいんじゃない?」って、いつも考えながら書いているのですが、ことごとく外れます。悲しい。
私は見やすさ重視なので、こんな書き方がしたいのですが、VBAのエディタは「ダメだよ〜ん」といいます。
Dim Paul as Integer
Dim Jhon as Integer
Dim Ringo as Integer
Dim George as Integer
if( type==NAKAI ){
else if( type==Kusanagi ){
else if( type==INAGAKI ){
else if( type==KIMURA ){
}
しかも、TABを打っても 4つのスペースになってしまう。かと思えば、ときにはTAB保持していることもある。よくわからないです。ちょっと残念に思います。
でも、みなさんのおかげで、問題は解決しました。ありがとうございました。とても助かりました。 これから、マイコン側のプログラムです
>>750 インデントとかは慣れちゃったらこれはこれでいい感じなのよ、統一取れて。
方便一切なしだから、よほどの事がなきゃ他人のコード見てもギョっとする事もないし。
>>751 途中のスペースが1個に固定されるだけでインデントは自由にできるでしょ
コメントの位置も自由だし
あちこちのサイトからコピペしてきたおかげで、数行ごとにインデントの幅が変わってガタガタってのもありがち
Java系やC系が長い人は変数名の後ろのインデントを揃えたがる人が多いように思う。 VB系の人はあまり拘ってない気がする。
>>750 if文のインデントはその通りに出来るはずだが?(先頭は自由)
Dimの先頭も可能、変数名〜As句もインデント可能。Dim〜変数名が無理なだけ。
結局お前、よくわかってないだけじゃねーかw
中間の無意味な空白はたまに入れたくなる時があってうーってなるけど、
仮にそれを許すと、
>>752 の言う各区切りスペースを1個に補正する機能が機能しなくなる
その整形に作業に時間取られるのは嫌じゃないのかね? 結局慣れの問題のような気が…
まぁコピペ時のTab残ったり無かったりはアレだけど、
通常入力時に混在出来るより遥かにましだろ 全角スペースも消えてくれるし
触れてない部分は勝手に改変しないことが保証されているって考えようぜ
つーか「TabがTebが」って言う奴は、
たいてい文字(複数行)選択中にTebキー押すと行全体(複数行全体)を一気に時下げしたり
Shift+Tabキーで一気に字上げしたり出来る機能を知らなかったりする
知ってたらそこまで怒り狂わないんじゃねーか?と思うのでぜひ体得してくれ
>>753 どうせあちこちで補正されるから
そういう些細な拘りはとっくに捨てました
>>754 Tabキーの複数行字下げは便利ですよね
756 :
デフォルトの名無しさん :2011/01/31(月) 04:39:29
TABで書いた直後に、お〜っと間違えた、という時に、BSで「4回も」戻さなければならない。 語句間が常に1スペースに「自動的になってしまう」 予約語の先頭がいつも大文字に「自動的になってしまう」 >全角スペースも消えてくれるし >Dimの先頭も可能、変数名〜As句もインデント可能。 それらをoffにできるoptionがあればいいだけのこと。 それらの「とても親切な機能」がoffにできるoptionがあって、 デフォルトinstallしたときには「全部off」になっていれば、 最高のエディタなんだけどね。 要は、自分の思い通りのレイアウトをさせてくれればいいだけ。 それだけなんだ。
757 :
デフォルトの名無しさん :2011/01/31(月) 07:46:15
>>756 > TABで書いた直後に、お〜っと間違えた、という時に、BSで「4回も」戻さなければならない。
undo(ctrl+z)すれば?
>>756 が慣れてないことは明白だし好みがあるのは否定しないが
"予約語の先頭がいつも大文字に「自動的になってしまう」"
というのは気をつけた方が良いと思われ
多くの言語で、変数名や関数名などの大文字と小文字は別の文字として
扱われるので注意
だからVBAでは自動的に変えて間違いを起こさなくしている
>>756 > BSで「4回も」戻さなければならない。
それこそ、その瞬間にShift+Tabキー押せば良いんでない
ちなみにそのオプションがあったとしたら、
複数人がコードを触る時はどういう振る舞いをするんだい?w
どうせその中でルールを決めてそれに縛られるんだろ。
いっそ全世界全員同じルールってほうが好ましいと思うよ。
>予約語の先頭がいつも大文字に「自動的になってしまう」 これって切ることできるの?
切れない
裏技でDimで宣言してから消すと小文字になるけど素人にはオススメできない 玄人はこんなことしない よって誰もやらなくていい
Excel2000のVBAで、以下の関数を作ろうとすると 何度やってもお尻1文字を忘却してしまうんですが… Public Sub 全セルの削除() ↓ Public Sub 全セルの削() 文字「セ」が気に入らないようで。 文字組合せによってはセより後ろ全体が文字化けしたり… (2003では大丈夫みたいです) これ…2000では回避不能な問題ですか? 困ったなぁ…他にもダメ文字ってあったりします?
764 :
デフォルトの名無しさん :2011/02/01(火) 00:42:04
VBAばっかりやっている人は、慣れてるし、どんなお節介も苦もないと思う。 でも、複数の言語を使うようになると、 こんなに親切なのは、マイクロソフトの製品を除いて他に無いことがわかる。 僕たちは、 ・自分の思ったようにレイアウトしたいし、 ・予想できる動きをして欲しい。 ・頼んだこと以外は勝手に親切しなくていいんです。(しないで欲しい) ちなみにCでは、 if(xxx==d){ a=b; e=f; w=q+u; } のように、1行に続けてたくさん書ける。 N88ベーシックではマルチステートメントとか言ったような気がするけど、 VBAでもできますか? if(xxx=d) then a=b : e=f; : w=q+u; Endif という感じで。
こんばんわ、質問させてください。 OS:XP sp3 Office:2003 複数のシートからデータを集めてレポートを作成するマクロを作成しています。 データの数は可変で、出力後のレポートのデータ数も比例して多くなります(シートは1枚です。) 今やろうとしているのが、出力後のレポートのデータの多さによって適切な印刷用紙と向きを設定してやりたいのですが、 現状だとA4縦、A4横、A3縦、A3横の設定にそれぞれ With ActiveSheet.PageSetup .PaperSize = xlPaperA3 .Orientation = xlLandscape End With といった感じで毎回ページ設定→その設定での総ページ数を確認し、最終的に適切な設定を決めています。 上記のやり方だと、用紙サイズと向きを変更する度に処理の時間がかかってしまい、あまり効率的ではありません。 もっと処理時間を短くできるような方法があれば教えていただけないでしょうか? わかりずらい質問で申し訳ありませんがよろしくお願いします。
>>764 N88-BASICはMicrosoftの製品です。
同じMS製であるVBAもN88-BASIC時代の名残があちこちに残っています
普段は書く人はいませんが、実は行番号を付けることもできますし、
マルチステートメントもN88-BASICと同じ書き方で使用可能です
あまり行儀が良くないので普通の参考書には書いてありませんが、For文もIf文も
1行にまとめて書くことが可能です。この場合はEnd Ifは不要です
>>765 ページ設定の処理速度はプリンタドライバに依存する
ドライバの反応が遅いと時間がかかる
VBAだけではどうしようもない
>>763 多分2000固有のバグ(仕様)。基本的に諦めて下さい。
VBA自体の文字コード変換にまつわるバグに関連してるかも。
2000上のVBAではStrConv関数のvbNarrowとvbWideもおかしな結果を返すし。
どうしてもというなら、
コード更正機能が「弄った時」に「1度だけ」しか動作しないのを逆手にとって
コピペ時の挙動(致命的構文エラーがなければ更正しない)を応用すれば入れられるかもしれんね。
あ、エクスポート→メモ帳記述→インポートもOKかも。
何かの拍子に破壊される可能性大なのでそこは本当に注意ね。Private内では絶対禁止レベル。
>>766 よく知ってんねぇ俺たまに使うよ。
EndIfすら煩わしいほどシンプルな時とか。(俗に1行If構文、1行For構文と呼ばれるね)
でもブロック内はコロン不可(1命令内だから)で、1行分の内容しか書けんのが弱点。
(コロンを入れようとしても通常の複数行If構文に補正される)
>>764 1行にしたいなら、1行If構文かコロン酷使でどうぞ。こんな感じ。
例:(それぞれ上が1行If、下が通常If)
If Flag Then Exit Function Else Flag = Not Flag
If Flag Then: Exit Function: Else: Flag = Not Flag :End If
If Flag Then Exit Sub
If Flag Then: Exit Sub: End If
もし万が一だけど「コロンがウザイ」って話なら何言ってるの?って感じだ。
逆にC言語なんか毎行セミコロン必須でウザくねーのかとw
そこは根本的な設計思想の相違で相容れるわけがない。
(キリストが存在するかどうかをキリスト教徒と仏教徒が言い合っても無意味だろ?)
ついでに マルチステートメントって厳密には「1コード(1行)内にいくつかの任意コードを記述出来る命令文」って事です。 漠然と「複数行のコードを1行にまとめる事」って意味でとらえてる人多いけど。名前紛らわしいし (ちなみに ステートメント = 組み込み命令文 ≒ 1コード ≒ 1行 です) 本来のIf構文だと 開始宣言/式評価(If〜Thenステートメント) 中身(ユーザーコード・省略可) 終了宣言(End〜Ifステートメント) で最低2つのステートメント(2行のコード)が必要だけどそれを1命令で実現!って意味。 基本制約である「1コードは1行内に記述しなければならない」ってのは当然1行If構文も例外ではないので、 それがThen〜Else間にコロンを設置出来ない理由だったりする。 一行If構文でのThen〜Else内の記述はそれ自身も「一行If」という1コードの部分となるのでその途中で改行は許されない。 そして改行と等価であるコロンについても当然のごとく許されない。 (改行したら2つのステートメントとして解析され、1行Ifとしては構文エラー、って寸法) 結局、If〜Then間や、For〜To間に改行を入れらんないのとまったく同じ理由。 よーするに絶対に改行を省略出来ないVB言語に対して、苦肉の策(反骨精神)で生まれたのが マルチステートメントという改行を一切受け付けない孤高の存在w
>>768 ThenとElseの間にもコロンは置けますよ?
If a = 1 Then b = 2: c = 4 Else b = 3: c = 6
文法も動作もN88-BASICのままです
For〜Nextも同様です
>>770 ごめんなさい。完全に勘違い恥ずk(r
信じ込んでたのに何かしらの外部エディタの校正仕様とかだったのかも…
そうか出来る子だったのか…ありがとう夢が広がりましたw
ところで、a=0,b=0のとき下記コードは何が表示されると思う?
If a Then If b Then MsgBox "hoge" Else MsgBox "nyoro"
正解は表示されない。ここ一行Ifの一番嫌いな側面。
ちなみに下記をコピペするとエディタが面白い冗談を言うよ!(VB6でも同様)
If 1 Then If 2 Then MsgBox "hoge" Else Else MsgBox "nyoro"
…上を踏まえて下記をコピペすると何も言わずにギャグをかますよ!
If 1 Then If 2 Then MsgBox "hoge" Else: Else MsgBox "nyoro"
そこまで1行に拘る理由がわからん
単に感性の問題だろ、しかも個人的な それ以上でも以下でもなく 「自分から見てエレガントかどうか」という指標 わからない者にはわからない わからなくても問題ない 一般的に言い出すほうが問題児 趣向を共にする奴が相手してやればいい
いや、おかしいだろ。明らかに。
775 :
デフォルトの名無しさん :2011/02/01(火) 19:20:07
そこで7行プログラムですよ
776 :
765 :2011/02/02(水) 00:28:01
>>767 返事が遅くなりました。なるほど、ドライバ依存なのですね。
それがわかっただけでも十分です、別の方法を探してみます。ありがとうございました!
「続ExcelVBAのプログラミングのツボとコツが絶対に分かる本」を読んでいます。
この本の372ページのコラム「オリジナルのカラーパレットを作るには」に、
フォームにラベルを並べて作るカラーパレットが載っています。
通常のやり方だと、ラベル一つ一つにつきイベントプロシージャを書く必要があるが、
クラスモジュールを使えば1つのイベントプロシージャで済むとのことです。
ですが、具体的なやり方については、載っていません。
どなたか、具体的なやり方が分かる方、教えてください。
(私は、クラスモジュールを使ったことがありません。)
よろしくお願いします。
参考:
http://books.google.co.jp/books?id=ABkRD4oYrQoC&pg=PA149&lpg=PA149&dq= excelvba+%E3%82%AF%E3%83%A9%E3%82%B9%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB+
%E7%AB%8B%E5%B1%B1+%E7%A7%80%E5%88%A9&source=bl&ots=UjaELK0-l2&sig=
vZI_Ey8cTllRBeK4iou8PlkWHeM&hl=ja&ei=OC9ITc7wOoO3cJqBueIC&sa=X&oi=book_result&ct=result&resnum=
1&ved=0CBgQ6AEwAA#v=onepage&q&f=false
778 :
デフォルトの名無しさん :2011/02/02(水) 01:34:02
あるバッチプログラムがあるとします。 (バッチプログラム内のソースはXCOPYを実行するプログラム【フォルダのコピー】) そのソース(下記コマンド)をエクセルシートに 列ごとに出力する にはVBAでは、 どのように記載すればいいのでしょうか? 例:call D:\MT_XCOPY.bat D:\test AAAAA_yymmdd(※一ヶ月分) →A列に出力。 call D:\MT_XCOPY.bat D:\test AAAAA_yymmdd_yymmdd(※二ヶ月分) →B列に出力。
>>777 クラスを理解するのは本当に大変だって事は覚悟しとけよ
オブジェクトって何ですか?レベルなら使いこなせるまで相当時間かかるよ
その覚悟があるなら、あとは
>>780 の通り
>>778 テキストファイルを読み込むコード書いて、
1行ごと取り出して好きなように判定して、
お好きなセルに書き込むだけの簡単なお仕事です。
782 :
デフォルトの名無しさん :2011/02/02(水) 10:11:59
すみません、非常に簡単な質問かもしれませんが、 Sheet1のA6という一つのセルを、Sheet2のA6、A68、A130・・・、Sheet3のA6、A68、A130・・・と規則正しく参照していきたいと思っているのですが どのようにすればいいのでしょうか? 例えばSheet2のA6に「=Sheet1!A6」と打ち込めば同じ値が表示されますが、下に下にコピペしていくと、Sheet2のA68はSheet2のA68と同じ値になってしまい困っています
やりたいことがよく分からんがSheet1!$A$6のことか?
>>782 何をしたいかよくわからん
VBA内で値の参照さえ出来ればいいのか?
数式が書き込まれたシートが出来上がればいいのか?
で、ここはVBAのスレなんだがそこは間違いないか?
とりあえず
Range("A1").FormulaLocal = "=Sheet1!A6"
この式がどういう意味かわかるか?
64ビットのExcelってVBAは遅いものなの? 同じマシンのVista(32bit) + Excel2010(32bit)に比べ、Windows7(64bit) + Excel2010(64bit)は 軒並み20%から30%くらい時間がかかるようになった。 2010評価版は2007より速かったのに正規版になったら遅くなってるし、踏んだり蹴ったりだな。
Core2Duoが出た当時、 「Core2Duoは(AMDと比べて)OSが64bitだと遅い」 と評判だった
>>782 エスパーする
=Sheet1!$A$6
という風にAと6の前に半角の『$』をつける
ちなみに、ここはエクセルマクロのスレですので
別のところで聞いた方が良いかな
>>786 まさしくCore2Duoなんだよね。
ノートパソコンはWindouws7(64bit)とExcel2010(32bit)で、さらに2倍くらい
時間がかかるが、これは別パソコンだから比較にならんな。
誰か同一マシン同一OSで32bitと64bitのExcelの比較やった人いないかな。
Core2Duoなどに実装されているIntel64は AMD64のインテルによる実装。 元々はインテルがマイクロソフトから、 「AMDと同じ機能を持ったCPUを作って」 と注文されて仕方なく作った機能
790 :
745 :2011/02/02(水) 14:41:48
すると、ノートブックのWin7+64bitは、XP32より遅いということ?
>>789 そうかOffice2010の64bitのためだけにWindows7の64bitを買ったんだが、遅くなっちゃ意味ないな。
それに今のマシンじゃメモリはDDR2の4GBが限界だし、マザーボードとCPUとDDR3メモリ買おうかなぁ。
>>790 XP32は持ってないが、とにかくおれんとこじゃノートが一番遅い。
CPUがモバイル用のU2300 1.20GHzだからしょうがないと思うけど。
794 :
デフォルトの名無しさん :2011/02/02(水) 20:15:07
>>781 テキストファイルを読み込むコード書いて、
1行ごと取り出して好きなように判定して、
→そのコードを教えてください。(判定も含めて。)
>>793 うほ、めっちゃ遅いやんw
ほんと、バージョンが進むたびにことごとく遅くなってくなぁ…。
(最初PtrSafe絡みで遅いのかと思ったら単にセル代入だし、
たった1回の関数コールが600ミリ秒も増加する原因とは考えにくいし)
>>794 問題は切り分けてやったんだから、あとはグーグル先生がいくらでも知ってるだろw
「VBA テキストファイル 読み込み 行単位」くらいでいいんじゃね?
>>794 今どこまで出来てんの?
コードカキコしてみ、一緒に考えてやるから(ニヤニヤ
Variantの初期化って出来ますか?? 一度代入を行った後でDim直後と同じ状態に戻したいんです 今は空のVariant変数を作ってそれを代入してます Dim varData, varZERO varData = varZERO '変数のくりあ! なんかこれ、間接的で気持ち悪いなぁと。。。(ちょっと無駄だし) スマートに「こう書けよjk」ってないでしょうか??
799 :
デフォルトの名無しさん :2011/02/03(木) 00:57:00
>>798 varData = Empty
ではダメか?
varData=Empty 配列なら Erase varData()
被った…w リロードし忘れorz
Variantの話じゃなくてすまん、ユーザー定義型だったら方法ないよね? 配列になってたらEraseでいけたと思うけど。
ない
804 :
777 :2011/02/03(木) 04:58:48
>>780 分かりやすいサイトを紹介していただき、ありがとうございます。
シンプルなものですが、クラスモジュールを使ってカラーパレットを作ることができました。
ラベルを配列にしたからか、イベント処理をフォーム側には書けませんでした。クラスモジュール側に書いたらできました。
正直あまり理解できていませんが。
>>798 ,
>>800 おぉーEmpty値を代入すればよかったんですね!
おかげ様でこれからはスマートに書けますよ、ありがとうございましたー
807 :
デフォルトの名無しさん :2011/02/03(木) 18:42:16
全シートの全セルをコピーして一つのシートに移動させたいんですけど、 Worksheets.Select Cells.Copy Sheets("Sheet1").Select Range("A1").PasteSpecial Paste:=xlAll なぜこれでできないんですか?お願いします
何がやりたいのか判らんが Cells.Copy と(シートを指定せずに)書いた場合、アクティブシートのすべてのセルを表す Range オブジェクトが返される 従って、シート1がアクティブシートならば、シート1からシート1がコピーされる そもそも、各シートの全セルの個数は同じなのだから、それをひとつのシートに 移動は無茶だと思う
809 :
807 :2011/02/03(木) 19:23:14
>>808 なるほどなぜできないかよくわかりました。
既に50個あるシートの中身を新規シートを作成し、その中に全て移すというVBAが作りたいのです
データの中身が判らないと何とも言えない まず、幾つかのシートのコピーを手作業で試してみたら? どういう風にやったらいいか見えてくるかもね 通常は、使ってる範囲だけを位置をずらしながら、 コピーすればよいという事になるとは思うけど シート1の情報 シート2の情報 シート3の情報 などなど
UsedRangeでいいんじゃないの?
812 :
デフォルトの名無しさん :2011/02/04(金) 02:08:09
A B 1 北海道 2 北海道 3 北海道 4 北海道 1 青森県 2 青森県 3 青森県 1 岩手県 2 岩手県 今こうなってるのを、 北海道のナンバーを全て1に。青森県は2に。岩手県は3に と、いった具合にVBAで組みたいのですが、どのようにすればいいでしょうか? もしくはなんとぐぐればよいでしょうか?
新しいナンバリングは何を元に決めるの? 出現順の連番でいいなら、出現リストを生成・保持しながらループする感じで 上から順にループ処理、値を順次取り出して出現リスト内にあるか検査 (1週目、北海道を照合) (結果A)リストにない→ 出現リストに新規追加し新しいナンバーを割り当て (1週目、北海道が1と決定) (結果B)リストにある→ 何もしない (2〜4週目の北海道など) この時点で新ナンバーは確定しているので、新ナンバーを該当セルの横に設定 これを最後のセルまで繰り返す 以上 出現リストはDictionaryオブジェクトを使うといいかな。 同時に新ナンバーのリストとしても使えるから。 Existsメソッドを重複検査に使用。FalseならAdd、値として新ナンバー入れとく。 あぁ、そういや存在しないキーでいきなり参照すると自動的にAddされる特性があるから、 NewNum=Dic.Item(県名)で、NewNum=0なら新ナンバー生成でもいいね(その場合0は新ナンバーに使用不可) つーかこれVBAでやるより作業用セルに数式書いてフィルしたほうが作業的には早いよ VBAでやりたくてしょうがないなら何も問題ないけど
>>812 A1=1
A2=A1+(B1<>B2) 以下オートフィル
>>814 それは同じ県はかならず一つにまとまってるって前提が必要だと書いといてやれよ
俺的にはどっかに県のコード一覧表つくっといてlookupが良いと思うぞ
VBAスレなのにVBAいらないけどな
>>812 のナンバリングってCOUNTIF使ってたりしてな。
>>815 LOOKUPじゃなくてVLOOKUPだろ?
はじめまして マクロでブック名を一括で変更したいのですが、 ブック名に文字化けを含む場合、エラーになります。 変更はNameを使用していますが、文字化けしたブック名を 変数に代入すると文字列が変わってしまう(â→a等)ようで、 変更前のブックのアドレスをうまく指定できません。 ブックを開かずに文字化けしているブック名を変更する方法はあるでしょうか?
>>818 ブック名でアクセスしなきゃいいんじゃね?
Workbooks(1).Name= "新しいシート名"
文字化けした名前を取り出したいってのは無謀だと思うぞ
つかなんで化けたのか
はじめまして質問させてください。 Excel 2007でInputboxから日付を入力してAutofilterしたいのですが うまく検索してくれませんコードは Private Sub Dim TMP As String TMP = InputBox("分析日を入力してください", "分析日入力", Format(Date, "yyyy/m/d")) If TMP = " " Then Exit Sub ActiveSheet.Columns("A:A").EntireColumn.AutoFit ActiveSheet.Columns("A:A").Select Selection.NumberFormatLocal = "yyyy/m/d" Selection.AutoFilter 'ActiveSheet.Range("$A$1:$P$255").AutoFilter Field:=1, Criteria1:=DateValue(TMP) End Sub です。 Criteria1:= 以降を "<>"&TMP や "="&TMP に変更しても 検索できませんでした。どうしたら検索できるのでしょうか?
>>819 横レスだけど、ブック名はユニコード、VBAの文字列はShift-JISベースで、一部の文字は
文字列変数に代入する時によく似た文字に勝手に変換される場合があるんだよ
海外から送られてきたブックなんかだとご当地の言語でブック名が付けられていたりして
VBAでまともに扱えなくて困る場合がある
>>820 私の環境では、試してみたらできたけど。
もちろん、プロシージャに名前付けてますよね?
>Private Sub
>>821 あぁそうか、Excelはオブジェクトなんだった
なるほど、Excel側のシート名はExcel管轄なのね…
ちなみにVBAはS-JISではなくUnicodeなんだが、まぁそれはともかくなるほど…
(VBは自分以外はShiftJISが基本だと思い込んでるので勝手にUni→S-JIS変換をかましてしまうのよ)
じゃ化けた文字列を再びシート名にする事は不可能か
ワークシートやVBAから名前で呼び出してたらアウトー、だな
>>820 貼り忘れでした。
Private Sub 分析結果の読み込み_Click()
このようにコマンドボタンに登録しています。
ちなみにどのやり方でできましたか??
>>824 A列しか入力してないけど、適当に日付を入れて、
>>820 のコードほとんどそのまま入力してできました。
$P$255を$A$255にしただけ。
>'ActiveSheet.Range...
のシングルクォーテーションは、実際は外しているんですよね?
簡単にデバッグできそうだから、どこかにシートをUpできるようなら見ますよ。
>>825 今試してみたけどやはり
254レコード中0件がヒットしました
となり検索できませんでした。
一度見てもらいたのですがUpする場所はどこがよろしいでしょうか?
>>825 斧にZIPでUpしました。添削のほうよろしくお願いいたします。
Sc_201766.zip
>>827 すみませんが、ダウンロードのキーワードを教えてください。
>>828 うっかりしてました。
2323です。
よろしくお願いします。
>>829 「参考.xls」のA列が日付じゃなくて文字列になっているのが原因。
はじめから日付にしておくほうがいいと思いますが、
どうしても日付にできないようなら、例えば、
ActiveSheet.Range("A1").Activate
Do While ActiveCell.Value <> ""
ActiveCell.Value=DateValue(ActiveCell.Value)
ActiveCell.Offset(1).Activate
Loop
のようなコードを分析日入力の後くらいに入力すればうまく働きます。
>>819 あと、文字列で検索するって割りきるのなら、最後の行のCriteria1を、
Criteria1:=Format(DateValue(TMP),"yyyy/mm/dd")
と変更してもうまく働きます。
832 :
831 :2011/02/05(土) 13:00:52
833 :
829 :2011/02/05(土) 14:19:19
>>832 無事できました!
マクロの記録で
ActiveSheet.Columns("A:A").Select
Selection.NumberFormatLocal = "yyyy/m/d"
としてA列を日付にしていたつもりなのですが
できていなかったのですね。
とても助かりました。ありがとうございました。
>>833 それは、良かったです。
あと、気になるところもいくつかあります。
If TMP = " " Then ... は、
If Not IsDate(TMP) Then
のような感じにしたほうが、いいと思います。
AutoFilterメソッドは、範囲を自動選択に任せて、
ActiveSheet.RAnge("$A$1:$P$255).AutoFilter ... を、
ActiveSheet.Range("A1").AutoFilter ...
にして、上の行のSelection.AutoFilterもいらないです。
A列が選択されたままになっているので、例えば、
ActiveSheet.Range("A1").Select
のような文をどこかに入れるなどしたいです。
(1行目には項目名が入っていると思います)
「$」記号は、セルの式のコピー、ペースト時の相対参照、絶対参照の区別のためにあるので、
VBAのコード内では、セルに式を入力するという用途以外では、無意味だと思います。
>>834 ご指摘のように修正させていただきました。
とても勉強になります。
また試行錯誤して分からないところがありましたら
よろしくお願いいたします。
>>819 >>821 返答ありがとうございます。
文字化けしてるのは海外のご当地言語が使われることもあるためです。
出来ればVBA上で一括管理したかったのですが、
Excelで文字化けしたファイルを扱うのは難しそうですね。
Excel以外のソフト等も使ってやってみます。
>>836 手元に2007しかありませんが、Excelのオプションで
言語設定があるようですが、これは役に立つかも?
使えなかったら、ごめんなさい
質問なんですけど 今インベーダー風のゲームを作っていてy座標の小さい方から大き方へ弾を撃ち出して 的に当て用途しているところなんですが 'ビーム砲が画面最上に達しているとき If lngBeamY = 144 Then 'ビーム砲発射フラグをOFF blnBeamF = False 'ビーム砲を消去 rngClear8.Copy _ Destination:=Range(Cells(lngBeamY, lngBeamX) _ , Cells(lngBeamY + 7, lngBeamX + 7)) 'ビーム砲が画面最上に達していないとき Else '縦位置の計算(縦移動) lngBeamY = lngBeamY + 4 'ビーム砲を描画 rngBeam.Copy _ Destination:=Range(Cells(lngBeamY, lngBeamX) _ , Cells(lngBeamY + 7, lngBeamX + 7)) End If というコードで的を外れて通り越して行ったとき弾を消し、次の球を撃てるようにしたいんですが 指定した座標を通り越しても移動を続け次の球が撃てません だれかアドバイスをください
>>838 'ビーム砲が画面最上に達しているとき
If lngBeamY = 144 Then
↓ ここを修正
If lngBeamY >= 144 Then
あと、上下が逆じゃない?
パソコンの画面のY座標は数学で習う座標と上下逆にするのが普通だよ
>>839 丁寧な説明ありがとうございます
上下逆にする覚えときます。
質問です。 VBAで、エクセル以外の画面をアクティブにできないようにする 方法はあるんでしょうか。
2003ではじめたばかりの初心者です。 写真をセル幅にぴたりとはめたいのですが、横幅がうまくいきません 写真の縦の縮小サイズから、横の縮小サイズを計算してセル幅に指定しようとしています。 Columns(buf).Width = Int(myHeight * ratio) アドバイスお願いします。
>>842 パッと見た感じだと、
myHeightじゃなくて、myWidthじゃないかと思いますが、
もう少し詳細を教えてもらったほうが答えやすいと思います。
>>843 すみません。
myHeightは、写真挿入前にポイントでセルの高さを指定しています。
写真は、縦のセルサイズに合わせて比率固定で縮小してます。
たとえば、セル縦300ポイント、写真縦横比が4/3だったら、
セルの横幅を400ポイントにしていすれば、写真とセルのサイズが合うかな・・・と。
この横幅のポイント指定が、1004エラーで上手くいきません。
>>844 Width を
ColumnWidth
にすれば、どうですか?
846 :
845 :2011/02/05(土) 22:57:03
ポイント単位だからColumnWidthは的外れでした。 もう少し考えます。
>>844 Width プロパティはポイント単位で取得のみ、
ColumnWidth プロパティは数字の「0」の幅の単位で、取得/設定可能。
なので、ピッタリした値にはなりませんが、
Dim xx as Double
...
With Columns(buf)
xx = .ColumnWidth / .Width
.ColumnWidth = Int(myHeight * ratio) * xx
End with
どうでしょうか...?
>>847 エラーの理由は理解できました。
ありがとうございます。
やはりぴったりにこだわりたいので、違う方法でもう少し考えて見ます。
>>848 そうですか。分かったらぜひ教えてください。
一応、
>>847 の誤差を小さくした改良版(?)も載せておきます。
Dim xx As Double
Dim preXx As Double
Dim num As Integer
...
num = Int(myHeight * ratio)
With Columns(buf)
xx = .ColumnWidth / .Width
Do
.ColumnWidth = num * xx
preXx = xx
xx = .ColumnWidth / .Width
Loop While preXx <> xx
End With
XPのExcel2007です。皆さんは時間計測を何でやってますか? 一定間隔で計測をやりたくなって、以下のようなサンプルを 作ってみました。今のところ、timeGetTime() でそれなりに 動いていますが、定石があれば教えて頂けないでしょうか? On Error Resume Next Cntr = 0 Tnxt = 0 Tsta = timeGetTime() While (Cntr < 100) Tnow = timeGetTime() - Tsta If (Tnow >= Tnxt) Then Worksheets("Sheet1").Cells(1, 1).Value = Tnow Cntr = Cntr + 1 Tnxt = Tnxt + 200 End If If ((Tnow Mod 1000) = 0) Then DoEvents Wend
>>850 一定の周期で処理を繰り返す場合の定石はSetTimer/KillTimer
852 :
850 :2011/02/06(日) 09:27:23
>>851 レスどうもです。
ループで待つのに抵抗があったところでした。
割り込みも試してみたいと思います。
多重ForEach文の中から1つだけ上に抜けたいんですが
Exit Forすると全部抜けちゃいます
1つだけ抜ける良い手はないでしょうか?
ForEachをやめてForとDoの入れ子にするってのもありますが、
3重4重のでもどうにかなる方法ないかなぁと・・・
>>851 一時停止時にコールバック受けたらExcelごとクラッシュするんでわ?
>>853 むーん。以下、Excel2007のヘルプのコピペ。
>Exit For
> For Each...Next ループまたは For...Next ループを抜け、Next ステートメントの次のステートメントに
> 制御を移します。For Each...Next ループまたは For...Next ループの中でだけ使用できます。
> For Each...Next ループまたは For...Next ループがネスト (入れ子) 構造になっているときは、Exit For
> のあるループの 1 つ外側のループに制御を移します。
とあるので、他に原因があるんじゃないかな〜
オレのところでも再現しなかった。
>>853 ソースを見せてください。
言語に限らず、基本的には1段階ずつしかループは抜けないはずですよ。
質問させてください。 Excel 2007でセルの計算式の結果を受けてIFで処理を分けたいのですが 上手くいきません。 具体的にはB1には=(480+(A1)*10)/480*F1) という式を入れており、その結果次第で 70以下ならC1に=(75-B1)*.48の計算結果をいれ、 70よりおおきければ − を表示させたいのです。 セルに直接IF文を入れることも考えたのですが、C1セルに 直接数値を入力することがあり(計算結果の微調整のため) マクロで計算させたいのです。 現在記述しているコードは Private Sub 計算_Click() Worksheets("sheet2").Select If Range("B1").Value <= 70 Then Range("C1").Formula = "=(75 - (B1)) * 0.48" Else: Range("C1").Value = "-" End If End Sub です。 これを動かしても何も表示されません。 どうすればよいでしょうか?
>>856 私の環境ではできました。
どこかにブックごとUpしてもらえれば見ます。
>>855 ネストしたループから一気に抜けれる言語はいくらでもあるよ。
例えば php とか java とか。
>>856 うちでも再現しない
> Worksheets("sheet2").Select
sheet1 見てるとかと言うオチじゃないよね?
まずは、ブレークかけてみて本当にそのルーチンが起動されてるか確認してはどうか。
>>856 斧でUpしました。
Sc_202214.zip
パスは9898です。
添削よろしくお願いいたします。
>>858 それは確認しています。
F8で確認しているのですが
If Range("B1").Value <= 70 Then
のところで実行時エラーがでます。
セルの結合が悪さをしているのでしょうか?
> 実行時エラーがでます。 おいおい、「動かしても何も表示されません。」じゃないのかよ。 エラーが出るなら、エラーメッセージ書くとか、エラーコード調べるとかしなよ。
>>861 たしかに・・・
自分で書き込んだ後に気付きました。
先ほど動かしてみたら以前はでなかったエラーが
でてきたのでテンパってました。
申し訳ありません。
>>860 B1がエラー値なんじゃないですかね?
たしかエラー値を含んでいると数値演算や比較式がエラーになったと思うんですが。
式に現れるA1とF1の中身は数式ですか?
その数式内でほかのセルを参照してませんか?
めぐりめぐってそのB1のValueを決定するために
今実行中、あるいはこの先埋めるはずのセルを参照してませんか?
あるいはほかのVBAが動作しようとしてるのかもしれず、
で、そっちでコケてるのかもしれません。
Excel自身にVBA関数を呼び出させた場合(数式からVBA関数を呼び出すとか)は、
VBAが中断モードになっていてもそれを無視して動作しようとします。
さらにその中で何らかのエラーが起きると何の表示も出さずに強制中断し、
このときValueの値はエラー値になります。
こうなると通常なら絶対にエラーにならないはずのセルがエラーを返したりと
イベント連鎖が読みにくくなりますので、その関係かもしれません。
>>859 拝見させていただきました。
結合したセルの値を参照/設定する場合は、
先頭セル(一番左上のセル)に対して行うと良いです。
If Range("L6:N6").Value ... ではなく、
If Range("L6").Value にする。
細かくExcelのVBAの仕様を調べてないので、
そのままでもいいところもあるかも知れませんが、変更してみてください。
865 :
デフォルトの名無しさん :2011/02/06(日) 13:08:32
シート1の最後のセル番地を変数に代入して、 シート2のオートフィルの範囲に適用したいのですが endcell = Selection.SpecialCells(xlCellTypeLastCell).Count ・ ・ ・ Range("a1").Value = "=trim(シート1!a1)" Selection.AutoFill Destination:=Range("A1:endcell"), Type:=xlFillDefault これではエラーがでます。セル番地を取得する関数はCountではないのでしょうか? そもそも変数の使い方が間違ってるのでしょうか?どなたかお願いします
>>864 上手くいきました!!
("L6")にしたり("L6:N6”)にしたりいろいろ
試していたのですがなかなか思うようになりませんでした。
この2週間ぐらいずっと悩んでいたのが解決しました。
Sub 計算()
Worksheets("Sheet1").Select
ActiveSheet.Range("L6:N6").Select
If Range("L6").Value <= 70 Then
Range("O6:P6").Formula = "=((75 - (L6)) * 0.48)"
Else: Range("O6:P6").Value = "-"
End If
End Sub
このように変更しました。ありがとうございました。
>>863 A1・F1はそれぞれ数値を入れています。
VBAは奥が深くまだまだ勉強することが多いです。
レスを下さった皆さんありがとうございました。
また分からないことがあればよろしくお願いいたします。
>>865 "A1:endcell"というのは、単なる文字列扱いされています
endcellという変数を与えたいなら、
Range("A1:"&endcell)
という形で書いてくださいな
他にもいろいろ間違えてそうですね
RangeオブジェクトのCountプロパティは単にセルの個数を返します。
でその書き方だと常に1を返します。(LastCellを指定すると単一のセルを返すため)
最終的に"A1:1"という文字列が出来上がってやっぱりエラーでしょうね
セル番地が欲しいなら、.Addressプロパティです。
ちなみに、LastCell指定をしたSpecialCellsは、
その元となる範囲を無視して、該当シート全域から最終セルを探してきます。
たぶん、望んでいるのとは違う答えなんじゃないですかね
・・・Excelのシートやブックって、なんであんなに壊れるのん? 急に動かなくなって、数日デバッグしてもどうしても原因わからなくて、 散々悩んだあげくシートを丸コピーして削除したらすっかり直ったり この怒りをいったいどこにぶつければ・・・
869 :
865 :2011/02/06(日) 13:48:45
>>867 ありがとうございます。お察しのとおりダメでした。
Dim endcell As Integer
endcell = Selection.SpecialCells(xlCellTypeLastCell).Address
Worksheets.Add Before:=Worksheets(1)
ActiveSheet.Name = "シート2"
Range("a1").Value = "=trim(シート1!a1)"
Selection.AutoFill Destination:=Range("A1:" & endcell), Type:=xlFillDefault
と、記述しています。
シート1の内容全てにtrim関数で空白を取り除きたいのですが、どのように記述するのが正しいでしょうか?
>>869 ワークシートの数式とVBAとを完全に混同しているのはわかりました
=Trim(A1)ってA1に入れたら循環参照しますよ?
1セル内に式と値を別々に入れることは出来ないでしょ
その内容でAutoFillが出てくるのはおかしいですね
今シート内の各セルには何かしら値があってその全セルの値にトリムを適用したいんですよね?
オートフィル使うと元々あった値の事はきれいさっぱり捨て去ります
シート全域の元の値を消し去る事になるはずですが、それでいいですかね?
おそらく各セルごとにTrimしたいんでしょうから、
この場合1セルずつ順番にTrimして回る必要があります
オートフィルのようにいっぺんには出来ませんし、
エクセルも助けてくれないので自力でコードを書く必要があります
Dim TargetCell
For Each TargetCell In ActiveSheet.UsedRange
TargetCell.Value = Trim(TargetCell.Value)
Next
ノーチェック、動作無保証。
で、ここは一応プログラマーのスレですので
もし「For文って何ですか?」レベルだったら出直して下さいませ
配列で処理したほうがずいぶん早いでしょうが、そんな話してもしょうがなさそう
演算子を変数で置いて数式の中で使用することってできないですか? op = + nf = 1 op 3 こううだとエラーになります
>>871 オペレータへの介入はVBAでは無理です
VB7より新しいVBならバージョンによって可能ですが、
VBAはVB6を祖とする(内部バージョンはVB6.1〜VB6.5)ものです
言語仕様は10年前のままで、オペレータに関しては何も介入出来ません
>>872 そうだったのですか
ありがとうございました
>>871 Sub test()
Dim plus As String
plus = "+"
MsgBox Evaluate(1 & plus & 2)
End Sub
あ、それありましたねw 彼への答えはそっちが適当なのかも 「何も」は言い過ぎでした
876 :
865 :2011/02/06(日) 16:51:18
>>870 できなかったです。
なぜセル全部にtrim関数を宛がうことがむずかしいのか私には理解できません。
よく使う処理であろうに。
勉強しなおしてきます。ありがとうございました
>>876 横レスですが、
状況がよく分からないので
適切なうまく動かないSampleを作成して、
どこかにUpしてもらえませんか?
>>876 できなかったですか、よくわかりませんがすいませんでした
いや難しくはないですよ。きっと造作もないです。ただ求めてる結果がわかんないです
(「ダメでした」だけじゃ何が起きたかすら分かりませんし)
> 〜よく使う処理であろうに
VBAはマクロ言語にしては異常なほど強力で、そのわり簡単だと思いますが、
逆にプの字も知らない人がほいほい扱える代物でもないです
無免許で突然ミッション車をうまく運転出来たならたいしたもんですよ
最初は誰だってそんなもんです
一行目に列タイトル、二行目以下A〜Fに数字が入っている表があります。 この票で「@A〜F内の数値の最小値」と「A最小値の列タイトル」をG/H列に表示したいです。 @についてはMIN(AX〜FX)(Xは行番号とする)で求められたのですが Aの@で抽出された最小値の1行目(CXが最小値なら、C1を返したい)の求め方が判りません。 アドバイスいただけると嬉しいです。
881 :
879 :2011/02/06(日) 19:42:21
>>880 早速誘導ありがとうございます、そちらのスレで再質問します。
スレ違い失礼しました。
882 :
865 :2011/02/06(日) 20:14:40
ご回答ありがとうございます。情報の小出しになってしまい申し訳ありません。
ttp://www1.axfc.net/uploader/Sc/so/202350.zip サンプルを用意させていただきました。
いくつかのセルにスペースでの空白が入ってしまっています。
セルの数が多く一つ一つ消すには時間がかかってしまいます。
なので、全てのセルに=trim関数を適用させたいと思っています。
セルの数は毎回変わってしまうので自動で宛がってくれるVBAを組みたい
といった形です。度々申し訳ございませんがよろしくお願いします
>>882 A1セルの#N/Aで引っかかるみたいなので、
>>870 のコードを改変して
Dim TargetCell
For Each TargetCell In ActiveSheet.UsedRange
If Not IsError(TargetCell.Value) Then
TargetCell.Value = Trim(TargetCell.Value)
End If
Next
で、どうでしょうか?
884 :
865 :2011/02/06(日) 21:34:54
>>883 ありがとうございます。完璧でした。
完全に勉強不足でした。
本当にありがとうございました
>>882 ,884
見返すといろいろボケたレスしてました、申し訳ないです。徹夜明けで失礼しました
循環参照〜とAutoFillの話は忘れて下さい(シートコピー部分を見落とし)
お詫びに元コード
>>869 へのアドバイスを上げときます
1)変数の宣言が数値型になってる
アドレス(文字列)を代入出来ないためエラーになります。正しくは As String
2)Address(0,0)が適当
引数を指定しないと$付きの絶対参照になります。今回の場合はフィル目的なので相対参照でないと
3)シート名が「シート1」以外だと失敗
大量に処理するならシートごとにNameプロパティから取得すべきかも
4)問題はないですがRangeは指定方法が幾つかあり、文字列での指定以外にもRangeオブジェクトでも指定出来ます
また引数2つで「Range(左上セル,右下セル)」という指定も出来ます。例えば範囲A1:F10のセルを指定するには、
Range("A1:F10")
Range("A1", "F10")
Range(Cells(1, 1), "F10")
Range("A1", "F10")
などなど。よって Range("A1:" & endcell) の部分は
Range("A1",Selection.SpecialCells(xlCellTypeLastCell))
とSpecialCellsを直接渡してしまう事も出来ます。
が、分かり難くもなります。都度その場に応じた分り易く短い指定法を選びます
5)オートフィル
一度の操作で両方向にフィルはできません。(マウス操作時と同じです)
範囲をフィルする場合は上下方向、左右方向に分けて2回実行します
指摘漏れててる AutoFillはSelectionからじゃダメよ いちいちセル範囲選択したくねーだろw
887 :
デフォルトの名無しさん :2011/02/07(月) 17:22:10
Excel2003には読み上げ機能があるので、これを利用して「英会話の数字の聞き取り」に特化した訓練マクロ(下記)をつくりました。 でも問題点があります。 Excelでは、4けたの数字は年代のように2けたごとに発声する方法(1456をfourteen fifty-sixと発話)になっていて、通常の方法(1456はone thousand four hundred and fifty-six)でしゃべってくれません。 これを改善するにはどうしたらよいでしょうか? Sub Number() Dim a As Long Dim b As Integer Dim c As Integer a = Int(Rnd * (10 ^ Int(Rnd * 5 + 3))) + 1 b = Int(Log(a) / Log(10)) + 1 c = Int(Rnd * b) + 1 Range("a1") = Int(a / (10 ^ (c - 1))) * 10 ^ (c - 1) Range("a1").Speak End Sub ちなみに上記のように複雑になってるのは、下記の点を工夫したためです (1) 日常でよく使う小さいけた数の出現頻度を多くする(最大で7けた) (2) 日常生活ではけたの多い数は概算で使われることが多いので、それに対応。(2456231のような1の位までの細かい数字ではなく、2450000のような日常的な数字の頻度をかなりあげる) (3) でも、たまには1の位まで細かい数字(2456231みたいな)も出題する。
>>887 状況がよく分からないので教えてください。
・シートに、例えば[もう一度]とか[次の問題]とかのボタンが貼り付けてあるのでしょうか?
・初めからA1セルに数字を表示するのですか? それとも[答え]などのボタンを押すと表示するのでしょうか?
どうせ考えるのなら、なるべく
>>887 さんのイメージに近い状態で考えたいので。
インタフェイスだけでも作って考えている仕様と一緒にどこかにUpしてもらえませんか?
889 :
888 :2011/02/07(月) 17:53:06
>>887 追加。
シートを使う意味が分かりません。
フォームの方がいいような気がします。
890 :
デフォルトの名無しさん :2011/02/07(月) 17:57:00
>>888 なるほど、インターフェイスがあると便利ですね
でもわたしは実はVBAの特にフォームを使ったインターフェイスはさっぱりわからないんです。
確かに[もう一度]とか[次の問題]とか[答え]のボタンがあると超便利って感じですよね。
あと、これはドリル練習なので大量の問題を一気に解くと力が尽きそうなので
繰り返し処理が必要ですね。まだそこらへんも含め全く考えていませんでした。
>>887 速度どうでもいい所でLogとか使ってると嫌われるよ
自力で数式を解決出来ないならなお更だよ…
孤高のプログラマー気取るのもいいけど
他人に質問するなら読みやすさも考えてくれよ
普通に考えて、入力数値を文字に置き換えて
前方からいくつか拾ってそれを対象に処理すればいいのにと思った
7桁の数なんだから文字列に置き換えても高々数バイトなんだし…
Randは(1)を実現するためのIf文に使おうよ
あとは出来上がった数値文字列を1文字ずつ処理して
「one thousand four hundred and fifty-six」等の英文を生成して
それを読み上げさせればいいんじゃない?
>>890 それでは、インターフェイスはとりあえず私なりに考えてみます。
飽きるか疲れたら止めますけど、途中でもできたところまではお見せします。
893 :
888 :2011/02/07(月) 21:02:11
894 :
888 :2011/02/07(月) 22:12:54
895 :
890 :2011/02/07(月) 22:14:30
>>888 すばらしい!!
ありがとうございます。
いまダウンロードしたばかりで少し使ったばかりですが
ものすごく見やすく使いやすいです。
まるで魔法みたいなツールですね。
あとは、この訓練は大量にやることに意味があるので
大量に解くときの使い勝手のよさ(例えばマウス操作をしないで、数値→Enter→数値→Enter→数値→Enter→・・・だけの操作で瞬時に次の問題にうつれるみたいな)
を考慮したいところです(自分には無理ですが)。
896 :
888 :2011/02/07(月) 22:32:36
>>895 カーソル移動用のコード追加です。
宣言セクションに
Const KEY_ENTER As Integer=13 'EnterKeyのKeyCodeは13
'フォーカス移動用
Private Sub AnswerTextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, Byval Shift As Integer)
If KeyCode.Value = KEY_ENTER Then
Call AnswerButton_Click
End If
End Sub
897 :
890 :2011/02/08(火) 00:04:36
>>896 ありがとうございます。
これで格段に使いやすくなりました。
すでに練習をしまくってますが
コツがわかってきて、thousandを聞いたらすぐにそれをコンマ( , )に脳内で変換し、
常に3ケタの数字を固まりとして脳にイメージすればいいことがわかりました。
よし、English板でもこのツールをみんなに紹介しようかな。
898 :
888 :2011/02/08(火) 00:45:03
>>897 あと、
AnswerButton_Click()のプロシージャの最後に、
QuestionButton.SetFocus
の一文を入れた方が使いやすいかも知れません。
タブオーダーについても、
出題→もう一度→解答欄→答えを見る→出題
と時計回りにした方が使いやすいかも知れません。
その人の使い方によるでしょうけれど。
899 :
888 :2011/02/08(火) 00:59:56
>>897 1桁の数字の出題率を0にしても、たまに1桁が出題されるバグ修正
問題作成のプロシージャ内の
Randomizeの下の
n = Rnd * denom を
n = Int(Rnd * denom) に
修正してください。
コンボボックスの項目がいくつあるか知る方法はどうすれば良いですか? With Me.Combobox .AddItem "a" .AddItem "b" .AddItem "c" End With この場合は3 With Me.Combobox .AddItem "a" .AddItem "b" End With この場合は2を取得したいです
901 :
900 :2011/02/08(火) 17:44:26
すいませんageます
Sort メソッドの昇順/降順を、プロシージャ-の引数で指定したいのですが可能ですか? その場合、データ型と呼び出し側の定数値は、どのようにすればよいのでしょう?
>>900 Combobox1.ListCount
>>902 定数は列挙型だからInterger型を使う
Dim so As Integer
so = xlAscending ' ソートのオーダー
Range("A1:A5").Sort Key1:=Range("A1"), order1:=so
おまいらExcel2007のソートのコーディングできる? 俺は記録マクロを頼りにしないとできない。
906 :
デフォルトの名無しさん :2011/02/08(火) 22:46:49
初歩的ですが誰か教えてください。 セル値(文字列)を数値に変換したいのですが、 数字以外の文字が入っているとエラーになると思います。 そこで、数字(0〜9)以外の文字が入っていたら その文字を消したいのですがどのようにすればよいでしょうか? 例. aw971d24h → 97124 replaceやsubstituteで簡単にかけるのでしょうか?
908 :
890 :2011/02/08(火) 23:26:29
>>888 ありがとうございます。ちょっと試してみます。
VBAでこんなことまでできるとはすごいです。
909 :
デフォルトの名無しさん :2011/02/09(水) 00:42:11
住所録の中から、いくつかの特定の住所の場合はその行の空欄のセルに△をいれるというVBAを作りたいのですが、 特定の住所というのが、住所1、住所2、住所3・・・と50個くらいあります。 延々と一つ一つ指定していくしかないでしょうか? できるだけ簡潔に書きたいのですが
911 :
906 :2011/02/09(水) 00:56:01
>907 できました!ありがとうございます! とてもわかりやすかったです。
>>909 例えば、
sub test()
const C as integer = 1 '住所のいくつ右のセルに△を入れるか
dim s,t 'ループ用
for each s in range("住所録")
s.offset(,c).value=""
for each t in range("特定住所リスト")
if s.value like "*" & t.value & "*" then
s.offset(,C).value="△"
exit for
end if
next
next
end sub
本日からVBAをさわり始めた超初心者です。 セルB4〜B6が全て空白でなかったらメッセージを出したいのですが、 下記のように記入し実行すると「実行時エラー 型が一致しません」 とエラーが出てしまいます。 If Range(Cells(2, 4), Cells(2, 6)).Value <> Empty Then "セルB4〜B6が全て空白でなかったら"という条件を作るにはどうしたら良いのか? どなたかご教示ください。
>>913 Sub check_blank()
Dim r As Range
Dim allBlank As Boolean
With Sheet1
allBlank = True
For Each r In Range(.Cells(2, 4), .Cells(2, 6))
If Trim(r.Value) <> "" Then
allBlank = False
Exit For
End If
Next
End With
If allBlank Then
MsgBox "全部空白!"
Else
MsgBox "全部空白じゃない!"
End If
End Sub
Rangeの前に . 入れるの忘れた。動くけど。
>>913 それは、別にVBAに限らず、例えば、3年2組の身長は何cmですか?
と尋ねているようなものだと思います。
組の身長を尋ねた場合、どう答えるのか? というルールが決まっている場合を除いて、
(例えば、組の身長を尋ねられたら、平均の身長を答えるとか)
普通は、○年○組のAさんの身長は何cmですか?
のように尋ねると思います。その場合、答えることが許可されていたら、
170cmです。と答えるでしょう。
すなわち、"セルB4〜B6が全て空白ではなかったら" という条件は、
セルB4は空白でないか、もしくは、セルB5は空白でないか、もしくは、セルB6は空白でないか、
と条件を立てるといいです。
Cells(2,4).Value <> Empty Or Cells(2,5).Value <> Empty Or Cells(2,6).Value <> Empty
慣れれば、
>>914 のように繰り返しを使えると良いです。
917 :
916 :2011/02/10(木) 00:03:33
>>916 行と列が逆だ。
>>913 も
B4からB6なら
Cells(4,2).Value <> Empty Or Cells(5,2).Value <> Empty Or Cells(6,2).Value <> Empty
最近、気づいたんだが、イベントプロシージャ単独、もしくはFSOオブジェクトを併用したら、マクロウイルスを作ること可能だよな?
スレ汚すな
↑おまえ粕。イベントプロシージャについて述べてるだけやん。
10年以上も昔の話をされてもなあ…… そんな方法は誰も引っかからなくなって廃れたんだよ。
922 :
デフォルトの名無しさん :2011/02/11(金) 12:14:02
2003つかってます。 UserFormを操作しているときに押されたキーを取得したいときは すべてのオブジェクトにkeypressイベントを記述しなければならないのでしょうか。 たとえば、UserForm_KeyPressなどですべて受け取れるようにはできませんか?
>>922 UserForm_KeyPressは非常に限られた状況でしか使えないので、
フォーム対するキー入力をまとめて処理したい時はAPIを使う
924 :
デフォルトの名無しさん :2011/02/11(金) 15:44:08
複数のブックを一つのブックにまとめるvbaを組んでいます。 ---------------------------------------------- Sub TEST01() Dim myObj As Object Dim myDir As String, myFle As String Dim ws As Worksheet, mb As Workbook, wb As Workbook Set myObj = CreateObject("Shell.Application"). _ BrowseForFolder(0, "フォルダを選択してください", 0) If myObj Is Nothing Then Exit Sub If myObj = "デスクトップ" Then myDir = CreateObject("WScript.Shell").SpecialFolders("Desktop") Else myDir = myObj.Items.Item.Path End If Application.ScreenUpdating = False '画面更新を一時停止 Set mb = ThisWorkbook myFle = Dir(myDir & "\*.xls*") 'フォルダ内のExcelブックを検索 Do Until myFle = Empty '全て検索 If myFle <> ThisWorkbook.Name Then 'ブック名がこのブックの名前でなければ Set wb = Workbooks.Open(myDir & "\" & myFle) 'そのブックを開きwbとする。 wb.Worksheets(1).Copy After:=mb.Sheets(mb.Sheets.Count) '1枚目のシートをコピー Set ws = mb.Sheets(mb.Sheets.Count) ws.Name = wb.Name '名前をwbのBook名に wb.Close (False) 'wbを保存しないで閉じる End If myFle = Dir 'フォルダ内の次のExcelブックを検索 Loop '繰り返す Application.ScreenUpdating = True '画面更新一時停止を解除 End Sub ----------------------------------------------
925 :
924 :2011/02/11(金) 15:44:50
>>924 というVBAです。
しかしエラーがでます。エラー内容は
------------------------------------
実行時エラー'1004':
Worksheet クラスのCopyメソッドが失敗しました。
------------------------------------------
なにが間違っているかわかりません。お願いします
遅延バインディング
927 :
924 :2011/02/11(金) 21:09:46
ダメだできない… フォルダにある全てのbookを一つのbookにまとめる。 シート名が被っている場合は自動で名前を変える (book1に東京シート、book2にも東京シートがあった場合はどちらかを東京シート(2)にするなど。) これが作れないせめてヒントだけでも…お願いします
>>924 とりあえずブックをUpしてください。
お互いの時間の節約のために。
929 :
デフォルトの名無しさん :2011/02/11(金) 21:28:16
wbがactiveになっていない
>>924 とりあえず試したら正常動作しました
一つ考えられるのは、多量のデータがあって問題があるのかも?
毎回、コピー終了後にセーブしたら動くかも?
931 :
924 :2011/02/11(金) 22:13:11
>>931 拝見させていただきました。
やっぱり
>>924 のコードから想像したのとかなり違いますね。
>>927 の件はExcelが自動でしてくれと思います。
私は、こうしてみましたけど、どうでしょうか?
Set wb = Workbooks.Open(myDir & "\" & myFle)
Call addSheetAll(mb, wb) 'ワークブックmb に ワークブックwbのシートを全てコピー
wb.Close(False)
...
Sub addSheetAll(mb As Workbook, wb As Workbook)
Dim i As Integer
For i = 1 To wb.Worksheets.Count
wb.Worksheets(i).Copy after:=mb.Sheets(mb.Sheets.Count)
Next
End Sub
933 :
924 :2011/02/11(金) 23:49:31
>>932 わざわざありがとうございます。
しかしダメでした。
------------------------------------
実行時エラー'1004':
Worksheet クラスのCopyメソッドが失敗しました。
------------------------------------------
とエラーがでます。
wb.Worksheets(i).Copy after:=mb.Sheets(mb.Sheets.Count)
ここがダメみたいです。
>>924 のコード、新規ブックにコピーして動く事は動いたのだけれど
そちらの状況が判らないです
一つもコピーできなかったのか、それとも幾つかはコピー出来たのか
バージョン情報なども聞きたいところです
935 :
932 :2011/02/12(土) 00:03:02
>>933 >>931 のサンプルで試してみたのですが…
931のサンプルでもエラーがでますか?
それとも別のブックでエラーがでるのでしょうか?
936 :
924 :2011/02/12(土) 00:10:33
バージョンは
Microsoft Office Excel 2007(12.0.4518.1014) MSO(12.0.4518.1014)
1.xlsの3つのシートはコピー完了しています。
それから
>>933 のエラーがでます。
もちろんアップロードしたサンプルで動くか検証しています
シートの名前が同じとか?
938 :
932 :2011/02/12(土) 00:19:28
939 :
924 :2011/02/12(土) 00:32:56
>>938 ありがとうございます。やはりダメでした。
940 :
932 :2011/02/12(土) 00:33:34
941 :
932 :2011/02/12(土) 00:52:36
>>933 >>932 のコードの
For i = 1 To wb.Worksheets.Count
と
wb.Worksheets(i).Copy after:=mb.Sheets(mb.Sheets.Count)
の間に、
Debug.Print wb.Name, i, wb.Worksheets(i).Name
Debug.Print mb.Name,mb, Sheets(mb.Sheets.Count).Name
Debug.Print
と入力して実行したら、
イミディエイトウィンドウにどのように出力されますか?
942 :
924 :2011/02/12(土) 01:41:16
>>940 ありがとうございます。解決はできませんでしたが、
別PCのexcel2003を使ったところ
>>932 のコードで動かすことができたので満足です。
本当に感謝です!ありがとうございました
せつねぇ
勝手に教えたがりやってんだから、放置されたからって粘るなや
>>924 のコードで疑問点あり
>myFle = Dir...
>Do Until myFle = Empty
Dir関数ではファイルがなくなった(ない)場合は
myFle="" (長さ0の文字列)が戻ると思っていたんだが
上記のmyFle=Emptyでもちゃんと動作するのはなぜだ?
だれか説明してくれぃ。。
VarCmpでVT_EMPTYとVT_BSTRの長さ0のVARIANTを比較すると VARCMP_EQが返されるから、とか言ってみる。 VBAの世界では、Emptyと長さ0の文字列は同じものと位で 考えておけばいいんじゃないかと。
emptyをstringに入れたときにどう暗黙変換されるかの問題だ。
950 :
946 :2011/02/12(土) 22:29:15
回答、ありがと。 VBAについてはそこそこ知ってるつもりだったが Emptyキーワードは、Variant型変数でしか使えんと思っとった で、投稿した後、ちょこっとテストしてみたところ、 Empty → 数値型 → 0 Empty → 文字列型 → 長さ0の文字列 として処理されてるようだな 今回は勉強になった、回答くれた皆に感謝!
Do Until myFle = Emptyなんてのはなんかいやだねぇ ところでおまいらTextBoxやComboBoxの未入力時のTextプロパティはvbNullStringと比較してる?
952 :
デフォルトの名無しさん :2011/02/13(日) 11:32:22
on Error Resume Next 難しいな 使わずに書こうと思ってたんだけど、使わないとどーしても避けれない処理がある Range.Pastespecial を使うときに on error resume next range.pastespecial on error goto 0 ってon error で囲まないとエラー時の対応が出来ない(解らない) どーしたもんか・・・
open とかのファイルを扱う際のエラー処理にも必須だと思うが...。 > どーしたもんか・・・ 書いてる通り on error で囲むだけだろ? 何が難しいのか、理解するのが難しいよ (w
一つの元データのあるブックから、複数のブックにデータを コピーしたいのですが、 Sub A08管理図の入力() Dim OpenFileName As String 'ファイルオープン Dim 転記元 As Workbook, 転記先 As Workbook MsgBox "最初の管理図を開いてください" ChDrive "D" ChDir "D:\結果" OpenFileName = Application.GetOpenFilename("Microsoft Excelブック,*.xls?") If O <> "False" Then Workbooks.Open OpenFileName Else MsgBox "キャンセルされました" Exit Sub End If Set 転記先 = ThisWorkbook 転記先.Worksheets("確認").Select としているのですが、 [ 転記先.Worksheets("確認").Select ] のところで実行時エラー’9’ が出ます。 転記先のシートが複数あるのでそれぞれ選択するにはどうすればよろしいでしょうか? ここで躓いて先に進めません。
>>951 Trim かけて "" と比較するのがよくない?
大したコストじゃないでしょ。
>>954 まず、エラーについて
元データブックを開いた段階で、転記先ブックがアクティブじゃなくなる
従って
Set 転記先 = ThisWorkbook
転記先.Activate
転記先.Worksheets("確認").Select
とする
次に複数のシートを選択するには、SelectのオプションReplaceを指定する
Worksheet オブジェクト.Select(Replace)
以下、Replaceについての引用
(シートでのみ使用) 既に選択しているオブジェクトの選択を解除して、
指定したオブジェクトのみを選択するには、True を指定します。
既に選択しているオブジェクトに加えて、指定したオブジェクトを選択するには、False を指定します。
957 :
954 :2011/02/13(日) 13:32:28
>>956 さん
私の書き方が悪く申し訳ありません。
転記元ブックはもともと開いており、このコードを記述しています。
[OpenFileName = Application.GetOpenFilename("Microsoft Excelブック,*.xls?") ]
で開くのは転記先ブックです。
いま見直して気付いたのですが、[Set 転記先 = ThisWorkbook]
が間違っているとおもうのですが、どう修正したらよいでしょうか?
Worksheets("確認")は後から開いた転記先ブックにあり、
Set 転記先 = OpenFileName
転記先.Activate
転記先.Worksheets("硬質").Select
としてもエラーが出ました。
>>951 If TextBox1.Text = "" Then
これじゃ拙いのか?
もしそうなら理由を請う!
959 :
956 :2011/02/13(日) 17:44:41
>>957 もう解決してるかもだけど
If OpenFileName <> "False" Then
Set 転記先 = Workbooks.Open(OpenFileName)
Else
MsgBox "キャンセルされました"
Exit Sub
End If
で、いいかなと
デバッグとかの使い方を練習した方が良いかと思う
960 :
954 :2011/02/13(日) 17:58:34
>>959 上手くいきました。ありがとうございました。
おっしゃる通りまだまだ勉強不足なので精進します。
助かりました!
>>958 色々Bingってみたりしたけど、結論としては、
vbNullStringは、ポインタに変換すると必ずNULLになる空文字列、
って感じっぽいな。
つまり、文字列として扱っている分には、""と全く変わらない。
""がポインタに変換された時、必ずNULLにならないかどうかは知らん。
TextBoxやComboBoxは未入力時は長さ0の文字列じゃなく値0の文字列を返すから If TextBox1.Text = vbNullString Thenがベターではある。 If StrPtr(TextBox1.Text) = 0 Thenでもよいが。
プログラムかいてると、 人間の判断力ってすげぇ って思えてくる
>>962 >TextBoxやComboBoxは未入力時は長さ0の文字列じゃなく値0の文字列を返す
これをはっきり示した資料あるか?
TextBox1.Textなんかだと、""代入してもvbNullStringになるっぽいが、
普通の文字列変数だとそうならないみたいだな
VBAでは通常NULLストリングとNULLポインタの区別をする必要はないんだし
API呼び出し等で明示的にNULLポインタである必要がある場合以外、vbNullStringは
使わない方がいいと思うが
965 :
958 :2011/02/13(日) 23:51:07
確かにstrptrでは0になるな
ただ、
TextBox1.Text = ""
TextBox1.Text = Empty
TextBox1.Text = vbNullString
これがみなTrueになるわけだから、
今回のことは知識として頭にいれとく程度でよさそうだな
それに、
>>964 も言っとるように、
またヘルプにも書いてあるように
vbNullStringは外部プロシージャの呼び出しで使うのがええような。。
何れにしろ、またまた勉強になった、ありがとな
966 :
デフォルトの名無しさん :2011/02/14(月) 20:02:06
web上にあるファイルをダウンロードするのに何かないかなと思って
探したらURLDownloadToFileというのがあって使ってみたんだけど
URLDownloadToFile(0, "
https://www.abc.com/123.xls ", "c:\", 0, 0)
プロトコルがhttpならOKなんだけど、httpsでsslが入るとダメ。
これって何かいい解決方法はないでしょうか?
それともVBAでhttpsでファイルを落とすのは無理?
分かる方是非教えてください!
968 :
デフォルトの名無しさん :2011/02/14(月) 21:46:56
>>967 ありがとございます!
ちょっと調べてみたのですが
Dim objHttp as Object buf As String
Set objHttp = CreateObject("MSXML2.XMLHTTP")
objHttp.Open "GET", "
http://www.abc.com/123.xls ", False
こんな感じのコードで上のコードで「http」の部分が「https」でも
OKということでいいでしょうか?
ちょっと今実行環境がないので。。。
ありがとございます!
ユーザーフォーム内でenterキーにhogeボタンを押したときと同じ動作をさせたいです ググりながらやってみましたが何か根本的に間違ってるような気がしてきました どうしたらいいのでしょうか? Sub UserForm_Initialize() Application.OnKey "{Enter}", "hoge_Click" End Sub Sub hoge_Click() xxx End Sub
>>969 そのフォームの中にボタンが一個だけで、他に入力や選択を行うコントロールが一つもなければ
何も書かなくても自動的にEnter=ボタンクリックになる
あと、Application.OnKeyはEnterには使えない仕様
972 :
デフォルトの名無しさん :2011/02/16(水) 18:19:07
もしスレチだったらすみません。 accessのVBAからADOでexcelに データを書きだしているのですが、 文字列扱いの数字にエラーインジケータが ついてしまいます。 これをVBAで解除することは できるのでしょうか?
>>972 最初からエラーチェックをしない設定には出来ないの?
Excelのヘルプで『エラーインジケータ』を見ると 色々出ていると思う ただ、データのコンバージョンでエラーが出た場合、 一応、すべて目を通さないとひどい目にあうかも?
975 :
972 :2011/02/16(水) 21:28:36
>>973 表示の有無設定ってツールオプションで行うので
ユーザの環境によって変わると思ってたんですけど
認識違いですかね?
>>974 ありがとうございます。
一度ヘルプも確認してみます。
976 :
デフォルトの名無しさん :2011/02/18(金) 20:55:48
VBAもいいかげんアップデートしてくれないものか せめて構造化例外とオーバーロードを・・・
GetOpenFilename等でユーザーが指定したファイルのパスをUNCパスに置き換える方法を教えてください。 自分ではパワーシェル等でネットワークドライブの一覧を取得して 割り当てられているドライブ名をコンピュータ名に置き換えるという方法しか考えつかなかったのですが、 それ以外に何かやり方はないでしょうか?
IF文で判定させたいのですが、変数 i が 60から55、55〜50のような感じで条件をだしてマクロを組んで見たのですが 上手く判定してくれません。 Dim i AS Integer i = Range("A1").Value If 60 >= i > 55 Then Range("B1").Value = "A" ElseIf 55 >= i > 50 Then .Range("B1").Value = "B" END IF どうしたら判定してくれるのでしょうか??
977です 978>> ありがとうございます!リンク先読んできました。 あるユーザーが指定したファイルを複数人で使う想定だったので 個人の環境に依存するネットワークドライブ名を使いたくなかったんです。 おかげさまでできそうです!
リンクミスった
>>978 さんありがとうございました!
>>979 If (60 >= i) And (i > 55) Then
>>982 上手く判定してくれました。
早いレスありがとうございました。
エクセル2002を使ってます。 あるセルの値をクリアしたら、その行のZ列の値もクリアしたいのですが、 Dim jissibiRow As Integer If Target.Value = "" Then 'あるセルの値をクリアしたら jissibiRow = ActiveCell.Row 'そのセルの行番号を出して Range("Z" & jissibiRow).ClearContents 'その行のZ列の値もクリアする とすると、Z列の値は消えるのですが、消えるまでに5秒程度かかってしまいます。 If Target.Value = "●" Then 'あるセルに●を入力したら(実際はプルダウンで入力) jissibiRow = ActiveCell.Row 'そのセルの行番号を出して Range("Z" & jissibiRow) = "実施済み" 'その行のZ列に実施済み"と表示 の場合は直ぐに実施済みと表示されるので、セルをクリアした場合の判定が間違っていると 思うのですが、どのようにすればよろしいのでしょうか?
985 :
984 :2011/02/19(土) 17:15:15
>>984 です。
少し状況が変わってきました。
Range("Z" & jissibiRow).ClearContents を
Range("Z" & jissibiRow) = "" にしても同じように時間が掛かったのですが、
Range("Z" & jissibiRow) = " " ”と”の間に半角スペースを入れると直ぐに反応するようになりました。
何も入れないと時間がかかるということは分かったのですが、やはり何も入れたくないです。
どのように修正すればよいかアドバイスお願いいたします。
>>985 部分的なコードを提示しちゃだめだぞぃ
Changeイベントを使っていると思うがそれだと
1.Range("Z" & jissibiRow).ClearContents
2.Range("Z" & jissibiRow) = ""
3.Range("Z" & jissibiRow) = " "半角スペースを入れる
上記1,2,3でもZ列のChangeイベントが発生する
そして、1,2では、
If Target.Value = "" Then
これに引っかかるからエンドレスになる
(実際はある回数で止まる)ので遅くなる
3では、If Target.Value = "" Then
に引っかからず即終了するから早くなる
●このようにChangeイベント内でセルに値を入れたら
そのセルのChangeイベントが発生するので
それを止めるコードを追加しなといけない
Application.EnableEvents = False '▼イベントOFF
Range("Z" & jissibiRow).ClearContents
Application.EnableEvents = True '▲イベントON
それから、
jissibiRow = ActiveCell.Row は
jissibirow = Target.Row の方がベター
csvを読み込んだんですが、数字として認識されません(セルの左上に緑が付きます) 「文字列のセルを数字にする」or「数字として読み込む」方法はあるのでしょうか?
ほ
>>987 御指摘のとおりchangeイベント使っておりました。
的確な回答ありがとうございました。
イベントを止めるコード勉強になりました。
Target.RowとActivecell.Rowの違いも調べます。
>>986 ありがとうございました。
こういうやりかたもあるのですね。勉強になりました。
次スレお願いします
自分で作ったユーザーフォームを実行中に、シートをいじれる状態にするにはどうすればいいですか 今はユーザーフォームが常に最前面に出てしまい、ユーザーフォームを消さない限りシートをスクロールすることすら出来ません
>>993 Showメソッドの引数に、 0 又は、vbModeless を指定する
UserForm1.Show 0 又は、vbModeless
詳しくはShowメソッドのヘルプをみれぃ
落ちる前に埋め
997 :
デフォルトの名無しさん :2011/02/21(月) 00:33:04.04
梅
lv低すぎてダメ
梅三郎
ありがとう。そして、さようなら。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。