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

Excel VBA 質問スレ Part33

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさん2013/10/17(木) 22:04:40.64
ExcelのVBAに関する質問スレです

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

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

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

コードが嫌な人はこちらのスレへ
http://toro.2ch.net/test/read.cgi/tech/1381151995/l50
0811デフォルトの名無しさん2014/06/21(土) 13:03:36.05ID:BHEAfygD
>>809
2013でも使えました。ありがとうございます。
0812デフォルトの名無しさん2014/06/21(土) 13:05:15.05ID:BHEAfygD
>>810
こんな検索もあるんですね。参考になりました。有難うございます。
0813デフォルトの名無しさん2014/06/21(土) 14:15:51.51ID:62Gltl9i
>>758
758です。色々ぐぐって自己解決できたのでコード載せときます
オフにするところの2行の意味がよく分かりませんが
希望の動作ができたから良しとします
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long

Private Sub Worksheet_Change(ByVal Target As Range)
Const VK_SCROLL = &H91
Const KEYEVENTF_EXTENDEDKEY = &H1
Const KEYEVENTF_KEYUP = &H2

Dim LockState As Boolean
Dim keys(0 To 255) As Byte

GetKeyboardState keys(0)
LockState = keys(VK_SCROLL)

'オンであれば強制的にオフ
If LockState = True Then
keybd_event VK_SCROLL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0
keybd_event VK_SCROLL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0
End If
End Sub
0814デフォルトの名無しさん2014/06/21(土) 15:51:17.12ID:MWnqmoLJ
Msgboxが表示された時にどのボタンにもフォーカスがない状態って出来ます?
はいやいいえになってると、Enter連打であっさりスルーされちゃうので

ぐぐっても「いいえ」に合わせるコードはでてきでも、
フォーカス無しのコードは出てこないし

msgbox("上書きしますか?",vbDefaultButton2+vbYesNo)

上のじゃないけど、ユーザーフォーム使うしかないんでしょうか?
0815デフォルトの名無しさん2014/06/21(土) 17:20:31.07ID:4JtY8OkT
どうせ見られないメッセージボックスなら出さない方がいいと思うよ
0816デフォルトの名無しさん2014/06/21(土) 18:03:25.68ID:Qjh9DMWW
> ユーザーフォーム使うしかないんでしょうか?
そりゃ当然だろ?

融通は利かないが、良く使われる用途なら簡素化できるってのが
MsgBoxを初めとする組込ダイアログなわけで
その仕様を外れたら自作になるのは、プログラムとしては当然のこと

MsgBoxではアレが出来ないコレが出来ないではなく、
本来なら全て自前でフォーム作らなければならないメッセージダイアログに置いて
特定の制限内の機能で事足りる場合はMsgBox関数で楽できるって考えるべき

つまりメッセージダイアログは、MsgBox基準ではなく自作基準で考えよう
0817デフォルトの名無しさん2014/06/21(土) 22:22:34.80ID:A7b0CBz5
>>814
おれスルーしたい時はESCだわ
0818デフォルトの名無しさん2014/06/21(土) 23:06:28.70ID:Ipr85krH
>>816
やはりそうですか…

今のところシートの中のVBA記述だけで作れていて
「シートコピーするだけで使えるマクロだから皆で使ってね」
って売り込みしたいので、ユーザーフォームは出来れば避けたかったのですが
まず開発タブを表示してVBEを開いて…とかだと多分みんな使ってくれない(汗

>>817
ESCやALT+F4は最初から無効みたいで、大丈夫でした

はい・いいえ・キャンセルを表示してフォーカスをキャンセルにして
キャンセル押したら再度Msgbox表示する方法で妥協を考えています。
ここを参考にしました。
http://www.excel.studio-kazu.jp/kw/20050314190246.html
0819デフォルトの名無しさん2014/06/22(日) 04:00:56.97ID:3PJ9Umqu
なぜそこまでしてフォームを自作することを敬遠するのか意味解らないw

MsgBox関数みたいに、メッセージの内容次第で幅も高さも可変で
いくつかのアイコン表示が出来たり、ボタンの数も種類も変えられたりするように作るなら面倒だけど
メッセージ内容もボタンも固定で、単にEnter連打で消えないようにするだけのものなら
1,2分もあれば作れるじゃん

ここで質問したりレスを読んだりするよりも短い時間で作れるものなのに
そんな簡単なことよりも、>>818の最後に書いてるような弊害を抱える方法で妥協するのは何故?
0820デフォルトの名無しさん2014/06/22(日) 08:34:28.55ID:icvg/MGo
変数がたくさん(100以上をイメージしてください)はいった配列変数があって
それを単純に昇順に並べるとき
VBAでわざわざ新シートつくってセルA1〜A100以降にわざわざ入力して
Excelのソート機能をわざわわざVBA呼び出して
そのあとわざわざ配列変数に入れなおすということをしています。
(この間ユーザに画面を見せないようApplication.Screenupdate = Falseにしています)

もっといい方法はありませんか?
やってること自体は単にアルゴリズムでいう「ソート」なので、新シート作ったりしないで、単に配列のソートをしたいだけなのですが。

ついでにExcel本来についている機能を利用するときそのコードがどうなって見れる方法とかありますか?
0821デフォルトの名無しさん2014/06/22(日) 08:35:41.60ID:icvg/MGo
とくに偉そうに説教してる>>819、なにかいい方法はないか?
0822デフォルトの名無しさん2014/06/22(日) 08:50:10.63ID:bqRgXzqb
excelのソート機能を呼び出すのが嫌なら自前でコードをごりごり書けば良い
配列のソートなんかいっくらでもサンプルがネットにある。
そうすれば、そのためにApplication.Screenupdate = Falseするのは回避出来る
0823デフォルトの名無しさん2014/06/22(日) 08:53:16.45ID:E7Bp6E2C
偉そうに説教してるという質問者が一番偉そうな件
0824桃白白 ◆9Jro6YFwm650 2014/06/22(日) 12:08:58.33ID:TaqxR0c4
>>820
(; ・`д・´)桃白白バブルソート実装しようか?
0825デフォルトの名無しさん2014/06/22(日) 12:09:12.69ID:HL9MA0On
>>820
>やってること自体は単にアルゴリズムでいう「ソート」なので、新シート作ったりしないで、単に配列のソートをしたいだけなのですが。
「ソート アルゴリズム」でググれ

ついでにExcel本来についている機能を利用するときそのコードがどうなって見れる方法とかありますか?
「メモリエディタ」でググれ
0826デフォルトの名無しさん2014/06/22(日) 12:42:39.60ID:LETTRPjp
質問者が偉そうと言うのには同意だが、

>>819
> なぜそこまでしてフォームを自作することを敬遠するのか意味解らないw

も相当頭悪そう
ちゃんと書かれてるやん
0827デフォルトの名無しさん2014/06/22(日) 12:46:42.79ID:rb15rihA
>>820
VBAにはソート機能がないので、ワークシートを使うかソートのプログラムを自分で作るのが定番
誰かが公開したやつをネットからコピペしてもいいし

それ以外には、Windowsのソート機能を使うという方法もあるけど、あんまり一般的じゃないしメリットも少ない
0828デフォルトの名無しさん2014/06/22(日) 14:14:21.42ID:28X7tRhT
そう言えばVBAってソート出来るObjectって使えるの無いんかな。
0829デフォルトの名無しさん2014/06/22(日) 14:15:56.96ID:ISsPU5R9
VBAにはソート関数が無いの?

PowerShellにもあるのに
0830デフォルトの名無しさん2014/06/22(日) 16:11:48.02ID:rb15rihA
>>828
いくらでもある
標準で入ってるのだとvbsとか.netの配列オブジェクトを使えばソートメソッドも付いてくるけど使うのがめんどくさい
0831デフォルトの名無しさん2014/06/22(日) 16:36:24.01ID:28X7tRhT
>>830
.Netの配列なんて標準でついてるんだ。
標準ってことはdllファイルとかにしなくても参照設定で普通に使えるってこと?
Ienumelableの実装とかどうなってるの?
0832デフォルトの名無しさん2014/06/22(日) 18:47:31.78ID:rb15rihA
>>831
CrerateObject以下略だけで使える
実装までは知らんけど、基本的な使い方はvbsの配列オブジェクトと似てる
0833デフォルトの名無しさん2014/06/22(日) 19:22:55.53ID:jr7Ep/EM
それって複数のマクロが各々異なるバージョンのアセンブリを利用する場合にも問題ない?
細かい話だが前から気になってるんだよ
0834デフォルトの名無しさん2014/06/22(日) 20:58:53.57ID:rb15rihA
もともと外部オブジェクトなんて保証外だわな
あくまでも自己責任で

半角文字のソート程度ならバージョンが違っても動作が変わることは少ないと思うけど、
あえてそこまでして使うメリットもあんまりないと思うんで、気になるならVBAでソートプロシージャを自作しとけ
速度が必要ならワークシート関数使った方がたぶん速い
0835デフォルトの名無しさん2014/06/22(日) 21:13:25.13ID:ut82qKlb
>>826
別にユーザーフォーム使ったところで、呼び出しをシートに書いておけば
「シートコピーするだけで使えるマクロだから皆で使ってね」
からは外れない故の慰問だろ?
0836デフォルトの名無しさん2014/06/22(日) 22:21:27.26ID:LETTRPjp
>>835
最初はいいとして、途中でユーザーフォームを変更するときは古いユーザーフォームを解放して新しいユーザーフォームをインポートしないとダメでしょ?
そのためには VBE から操作する必要あるし、そもそも最近のバージョンだと VBE 起動するための開発タブが表示されてなかったりしするので、一般ユーザーに説明するのは結構面倒だよ。
0837デフォルトの名無しさん2014/06/22(日) 22:40:03.01ID:waKqYOf3
ファイルを開くとwindows7のtaskbarにそのファイル
のアイコンが表示されますが、それを表示させない方法あり
ますか?ファイルを読み込んで、処理して、上書きする
自作プログラムを実行するとtaskbarがチラつくので、
それを防ぎたいのですが。理想的には画面に何の変化も
起こさずに一連の処理をしたいのです。
0838デフォルトの名無しさん2014/06/22(日) 23:09:10.40ID:jr7Ep/EM
>>836
メッセージボックスで済む程度のものを変更するとは思えんがな
0839デフォルトの名無しさん2014/06/22(日) 23:19:27.60ID:qKjZQIgF
>>837

>>554
0840デフォルトの名無しさん2014/06/22(日) 23:24:42.52ID:ut82qKlb
>>836
そこまで求めると、どっちにしろMsgBoxでは事足りないってことになるのでは?
0841デフォルトの名無しさん2014/06/23(月) 00:05:55.68ID:yjdH9XJr
普通はアドインつくるなり、プログラム用のエクセルからデータ用のエクセル開くなり
シートをコピーさせるなんて事すらやらさ無いように考えるものじゃないか
0842デフォルトの名無しさん2014/06/23(月) 00:19:12.81ID:3jaGUV4o
参照設定ってエクセル起動時に初期化されるの?
凄く不便なんですが
0843デフォルトの名無しさん2014/06/23(月) 05:40:10.13ID:PqswRIgE
>>838
ひょっとして、日頃から 〜とは思えん とか言いながらプログラム作ってるの? w
そもそもすでに運用してる人はどうすんの?
ちょっと考えればわかるでしょ。

>>840
言ってる意味がわからん。
俺が書いてるのは運用のやり方だよ?
0844デフォルトの名無しさん2014/06/23(月) 05:44:21.04ID:PqswRIgE
>>841
> シートをコピーさせるなんて

とか言いながら、アドインの導入はやらさせるんだよね?
ひょっとして、バカなの?
0845デフォルトの名無しさん2014/06/23(月) 07:19:07.68ID:PhFfpdUE
ブックではなくシートのコピーを想定してるって事は
作り手と使い手は同一のPCを使う状況なんだから
アドインの導入は、やらせるんではなく自分でやっておくわけでしょ

だから相手にはその負担は全く掛からない
0846デフォルトの名無しさん2014/06/23(月) 07:34:03.43ID:PqswRIgE
>>845
> 作り手と使い手は同一のPCを使う状況なんだから

>>818
> 「シートコピーするだけで使えるマクロだから皆で使ってね」
> って売り込みしたいので、ユーザーフォームは出来れば避けたかったのですが
0847デフォルトの名無しさん2014/06/23(月) 08:37:13.80ID:nXtrLFsL
最初にマクロ実行するときだけフォームのコードが生成されるようにしとけばいい
0848デフォルトの名無しさん2014/06/23(月) 08:43:58.27ID:hMj0GtJU
>>839
情報ありがとうございました。こんな便利な機能があったとは。
これでちらつきは防止できそうなのですが、ただ一つ困ったことは、
ユーザーがタスクバーに複数のxlsxファイルのアイコンを表示させて
置きたい場合、ShowWindowsInTaskbarをFalseに出来ません。
自作プログラムの実行前にFalseに設定して、実行後にTrueに
戻すと、プログラム実行中はちらつきませんが、その設定/再設定 自体がちらつきを
発生させてしまいました。
ということで、全く見えない非表示のワークブックを作成することは
出来ないでしょうか?あるいは何か別の良い方法ありませんか?
08498472014/06/23(月) 08:45:27.70ID:nXtrLFsL
>>818
> 「シートコピーするだけで使えるマクロだから皆で使ってね」
> って売り込みしたいので、ユーザーフォームは出来れば避けたかったのですが

これかな
http://blog.livedoor.jp/yorinaga/archives/51924953.html
https://www.moug.net/tech/exvba/0090027.html
0850デフォルトの名無しさん2014/06/23(月) 08:48:27.84ID:89oxU91p
>>843
>すでに運用
は?どこにも書いてないだろ?
0851デフォルトの名無しさん2014/06/23(月) 09:04:17.48ID:j+hyzfi+
別にフォーム使わなくてもさ、シートにオートシェイプ被せてからテキストボックスとボタンのっけて
ついでにフォーカス奪ったりしとけばいいんじゃねぇの
0852デフォルトの名無しさん2014/06/23(月) 09:25:36.13ID:89oxU91p
>>851
それ最後にメッセージボックス必要になるだろw
msgbox "メッセージを読み終わりましたか?"
0853デフォルトの名無しさん2014/06/23(月) 09:40:06.51ID:erXvHz+T
>>852
msgbox替わりの物をオートシェイプとボタンで作れって話でしょ
0854デフォルトの名無しさん2014/06/23(月) 10:07:28.30ID:N/NXR7eW
Msgboxのかわりに
メモ帳を開いてそこにメッセージを書くことってできませんか?

ユーザにはコピペしてもらう用途なのでそれが一番いいのですが。
0855デフォルトの名無しさん2014/06/23(月) 10:37:55.31ID:LmsmhY4T
>>850
ああ、すまん。
既に運用してるっつーのはなかったな。
まあ、運用途中で ぐらいに読み替えてくれ。
0856デフォルトの名無しさん2014/06/23(月) 11:18:51.46ID:h9OdHO6e
>>854
たぶんメモ帳でもできるんだろうけど
エクセルでシート上にメッセージを表示じゃだめなの?
そっちのほうが簡単じゃね?
0857デフォルトの名無しさん2014/06/23(月) 11:30:58.15ID:N/NXR7eW
>>856
シートは正式な書類だから変なメモが残せないから
わざわざユーザフォームを検討したり
わざわざメモ帳を検討したり
しておる。
0858デフォルトの名無しさん2014/06/23(月) 11:33:48.87ID:NJtDURlP
>>854
テキストボックスでいいじゃん
メモ帳の実態はテキストボックスだから、中でできることはまったく同じだよ
0859デフォルトの名無しさん2014/06/23(月) 11:34:47.35ID:NJtDURlP
またお前か
0860デフォルトの名無しさん2014/06/23(月) 11:48:00.55ID:N/NXR7eW
テキストボックスだと
もしユーザが間違って保存してしまった場合それがファイルにずっと残るじゃないか。
0861デフォルトの名無しさん2014/06/23(月) 12:01:31.36ID:NJtDURlP
>>860
TextBox1.Locked = True
0862デフォルトの名無しさん2014/06/23(月) 12:13:02.10ID:N/NXR7eW
>>861
それをしても、なにもかわらないじゃないか
0863デフォルトの名無しさん2014/06/23(月) 12:26:27.35ID:zCax8W1Q
質問です
myForm
0864デフォルトの名無しさん2014/06/23(月) 12:29:16.35ID:zCax8W1Q
なんか勝手に送信された

質問です
myForm があってその中に myButton があるとき
フォームのコード内からボタンをクリックするにはどうすれば良いですか?

Private Sub myButton_Click()
MsgBox "test"
End Sub

Private Sub UserForm_Activate()
Call myForm.myButton_Click
End Sub

としても駄目でした
0865デフォルトの名無しさん2014/06/23(月) 12:49:27.29ID:h9OdHO6e
>>864

Private Sub UserForm_Activate()
Call myForm.myButton_Click
End Sub
じゃなくて
Private Sub UserForm_Activate()
Call myButton_Click
End Sub
でいいんじゃないの?
0866デフォルトの名無しさん2014/06/23(月) 12:54:09.88ID:zCax8W1Q
できました!!
ありがとうございました!!!
0867デフォルトの名無しさん2014/06/23(月) 16:00:53.41ID:89oxU91p
>>853
そうなんだけど考えてみて
0868デフォルトの名無しさん2014/06/23(月) 16:22:31.21ID:h9OdHO6e
そんな手間かけるより使う人達にEnter連打するなって言えば済む話じゃないか?
0869デフォルトの名無しさん2014/06/23(月) 16:26:14.54ID:LmsmhY4T
そんなもんで連打しなくなるなら、ワンクリ詐欺とか激減するわけで...
0870デフォルトの名無しさん2014/06/23(月) 16:39:51.77ID:h9OdHO6e
そのメッセージボックスがいかなる状態で表示されるのか不明だけれど、
メッセージ表示のトリガーをマウス操作にすれば
(画面上の何らかのオブジェクトをマウスでクリックした後でメッセージが表示されるようにする)
Enter連打は回避できる
0871デフォルトの名無しさん2014/06/23(月) 17:33:26.97ID:ERNDPjz2
教えてください

  A  B    C  D
1山田 パンツ 100 
2(空白行)
3田中 パンツ 100
4    ステテコ 300
5(空白行)
6伊藤 パンツ 100
7    シャツ  200
8    靴下 400
9(空白行)

このように一人一人が購入した品物と金額が入った表を別のCSVファイルから取り込むマクロを作ってます
取り込みや体裁を整えるところは出来たのですが、わからないことがあるので教えてください。

D列に各顧客の合計金額を出したいのですが、顧客ごとの行数がまちまちなので範囲の指定方法がわかりません。
幸い顧客と顧客の間には必ず空白行が入るので空白行を目安に範囲指定すれば良さそうとは思うのですが方法がわからないです。
合計は名前のある行のD列に入れたいと考えてます。

不特定なの範囲での合計はどのように書けばできるのでしょうか?
0872デフォルトの名無しさん2014/06/23(月) 17:44:48.00ID:XnygHaO/
>>871
Endプロパティとか、ループでB列の空白を判定とかでいいんじゃね?

でもさ、そういう不適切な集計の仕方はやめた方がいいよ
集計が面倒になる原因って、難しいことをやってるからとかではなく
元データの形式や集計結果の出し方が不適切故に、
不適切なことを一発でやるための機能が備わってないから、
遠回りが必要になってるだけで、正しくやれば
ものすごく簡単に同じ結果を出せるんだからさ
0873デフォルトの名無しさん2014/06/23(月) 19:10:58.16ID:3o7GTMgO
>>867
https://friendpaste.com/6Efa456sVeLQgRAfYxFAHV
考えてみた
こんなんでいいんじゃないのか
0874デフォルトの名無しさん2014/06/23(月) 21:27:39.48ID:h9OdHO6e
>>871
まぁ、本来は>>872さんの仰る通りなんだけど、
コード書いてみたかったから書きました。

A列に名前がある行を先頭にして、B列で空白が出てきた行までの範囲の
C列の値を集計して、先頭行のD列に書き込むマクロです。
処理対象シートの下の方から順次処理をして、先頭行のD列が空白ではない時点、
もしくは先頭行が1行目になった時点で処理を終了します。

なお、With 〜 のところで処理するシートを指定しているので、
使用する際はここを適宜書き換えてください。

Sub test()
Dim rwA As Long
Dim rwB As Long
With ThisWorkbook.Sheets(1)
rwA = .Cells(.Rows.Count, 1).End(xlUp).Row
If .Cells(rwA, 1) = "" Then Exit Sub
rwB = .Cells(rwA, 2).End(xlDown).Row
Do
If .Cells(rwA, 4) = "" Then Exit Do
.Cells(rwA, 4) = WorksheetFunction.Sum(.Cells(rwA, 3).Resize(rwB - rwA + 1))
If rwA = 1 Then Exit Do
rwB = .Cells(rwA - 1, 2).End(xlUp).Row
rwA = .Cells(rwA, 1).End(xlUp).Row
Loop
End With
End Sub
0875桃白白 ◆9Jro6YFwm650 2014/06/23(月) 21:32:42.29ID:WlySWkx4
   ∩___∩
   | 丿     ヽ
   /  ●   ● |
   |    ( _●_)  ミ
  彡、    ヽノ ,,/    ♪
  /     ┌─┐´
 |´  丶 ヽ{ .茶 }ヽ
  r    ヽ、__)ニ(_丿
 ヽ、___   ヽ ヽ
  と____ノ_ノ
08768742014/06/23(月) 21:44:44.46ID:h9OdHO6e
あれ?
書き間違えてた。

If .Cells(rwA, 4) = "" Then Exit Do

じゃなくて

If .Cells(rwA, 4) <> "" Then Exit Do

です。
何で間違えたんだろ?
(多分、3行上からIf文をコピペして "=" を "<>" に直し忘れたんですね)
あと、表の開始行が1行目じゃないとエラーが出ますので、
その場合は

If rwA = 1 Then Exit Do

の1を開始する行に変更してください。
0877デフォルトの名無しさん2014/06/23(月) 21:47:48.46ID:eOLFLVwW
面談
「オブジェクト指向できる?」
「C#できる?」
「UMLかける?」

そして入ってみたらVBAの案件やった
なんでやねん
0878桃白白 ◆9Jro6YFwm650 2014/06/23(月) 21:54:21.02ID:WlySWkx4
>>877
超いいじゃん、うらやましい
0879デフォルトの名無しさん2014/06/23(月) 23:02:37.78ID:ZccyYMgG
>>877
あなたが全部できないから仕方なく?
0880デフォルトの名無しさん2014/06/23(月) 23:36:38.89ID:c5Kifoi8
818です。
メッセージボックスで白熱の議論になってしまい
ちょっとビックリしています

>>870
バーコードリーダーでバーコードを読んだ時に
それが過去に入力済みのバーコードだった場合に
「上書きしますか」とメッセージボックスが表示されるようになっています。
バーコードで読んだ管理番号を元に対象の行を一覧表から検索し、
入力者、入力日などの情報を追記・更新するプログラムになります。

トリガーはWorksheet_Changeイベントです。
机に沢山のバーコードラベルを並べて、連続で読んでいく入力方法を考えていて、
正確に言うと問題なのはENTER連打ではなくバーコード連続入力です。
バーコードを読んだとき最後にENTERキーが押されたのと同じ効果が発生するので、
メッセージボックス表示中に、次のバーコードを読んでしまった場合に
メッセージが飛ばされ、入力者が気づかない恐れがあると言った具合です。
0881デフォルトの名無しさん2014/06/23(月) 23:44:37.17ID:qAGmjPdg
>>880
>>873
ためせば
シートロックするからバーコードのキー入力も受け付けないんじゃね
08828702014/06/23(月) 23:54:40.63ID:h9OdHO6e
>>880
あぁ、そういうことですか。
作業中にEnter連打とか
どんなバカ野郎揃いの職場なんだと思ってました、ゴメンなさい。

そんじゃあ、Yes/Noじゃなくて、Yes/No/キャンセルの3つのボタンを用意して、
デフォルトをキャンセルボタンにしておいたらどうですか?

で、キャンセル選択時には再びメッセージボックスを表示するように無限ループにしておく。

あるいはメッセージボックス表示前とボタン押下後にNowで時刻を取得して
1秒以上(別に1秒じゃなくてもいいけど)経過してなければ
同様に無限ループとか。

閾値が1秒だとちょっと作業のテンポが悪すぎかもしれないんですが、
確かミリ秒単位で時間を計れるマクロがググッたらどっかに在った気がします。
0883デフォルトの名無しさん2014/06/24(火) 00:09:38.96ID:p/P3a7R3
>>881
>>882
回答ありがとうございます。

ますは、882のデフォルトをキャンセルにする方法で対応して、
ゆくゆくは873の方を導入したいと思います。
知らない機能を使ってるみたいなので少し勉強が必要そうです。
0884デフォルトの名無しさん2014/06/24(火) 00:26:03.63ID:Ti0c9rze
Yes/No/キャンセルとかじゃなくて、デフォルトNOのYes/Noだけで良い気がするが
0885デフォルトの名無しさん2014/06/24(火) 00:26:49.78ID:F5DFjMP3
Noとかキャンセル押してもダイアログが閉じないって悪夢だけどな
0886デフォルトの名無しさん2014/06/24(火) 00:50:31.53ID:5iFc+8Q+
>>884
Yes/Noだけだと、2つのうち1つはEnter連打を無視するのに使わなきゃならないから
本来やりたいデータの上書き確認が出来ないってことなんじゃないの?
0887デフォルトの名無しさん2014/06/24(火) 01:27:24.29ID:yc/rKAcg
>>885
悪質サイトにありがちな、入会しますか? で、どうあがいても Yes しか押せないみたいな w
0888デフォルトの名無しさん2014/06/24(火) 04:24:16.40ID:Ti0c9rze
ああ、Yes/Noがもともと必要なのか

上書きしますか?(はい/いいえ)
いいえ->上書きしませんか?(はい/いいえ)
いいえ->上書きしますか?(はい/いいえ)
いいえ->上書きしませんか?(はい/いいえ)
以下永久にループでw
0889デフォルトの名無しさん2014/06/24(火) 05:31:01.64ID:kCZG54Z4
そもそも・・・
0890デフォルトの名無しさん2014/06/24(火) 08:43:47.68ID:zV5ogSbP
 _________________________
 |Windows                          [−][口][×]|
 | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
 |  ハ,,ハ                                    |
 | ( ゚ω゚)  お断りしますが、よろしいですか?        |
 | ───                             |
 |    ______  ______   ______   |
 |    | はい(Y) || はい(Y)  ||  はい(Y) |  |
 |     ̄ ̄ ̄ ̄ ̄ ̄    ̄ ̄ ̄ ̄ ̄ ̄   ̄ ̄ ̄ ̄ ̄ ̄   | 
   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
0891デフォルトの名無しさん2014/06/24(火) 09:21:49.91ID:oDNeDxJ6
>>887
アメーバ会員の退会手順がそうだった
なんども退会しますか?ほんとうに退会しますか?って無限ループω
0892デフォルトの名無しさん2014/06/24(火) 10:43:03.21ID:jPo8ZSVb
>>874
サンプルコードありがとうございました。
こういうやり方があるの勉強になりました
0893デフォルトの名無しさん2014/06/25(水) 19:54:49.36ID:BILL5zsz
行ごとに羅列されたデータの最終行を取得するマクロを組みたいのですが、最後の方になるとエラーを含むことがあります。エラーが起きる直前の最終行の値を拾いたいのですが、どうすればよいのでしょうか。

エラーとなる言葉はNaNという言葉になり、ある行からNaNになれば以降はずっとNaNになるため、NaNの直前の行を取得できれば良いです。

もともと最終行は
.cells(rows.count,1).end(xlup).row
.cells(1,columns).end(xltoleft).column
で取得しています。
よろしくお願いします。
0894デフォルトの名無しさん2014/06/25(水) 20:17:48.86ID:vwnOk3e3
>>893
SpecialCellsを使えばいいんじゃないかと
>指定された条件を満たしているすべてのセル (Range オブジェクト) を返します。
なので

Set Err_Cell = Range("A1:A100").SpecialCells(xlCellTypeFormulas, xlErrors)
Set Before = Err_Cell.Cells(1, 1).Offset(-1)

とかとか
0895デフォルトの名無しさん2014/06/25(水) 20:39:19.00ID:5r4HS54B
>>893
>.cells(rows.count,1).end(xlup).row
>.cells(1,columns).end(xltoleft).column

みつかったセルから1行目まで順繰りに調べて行けばいいだけ
0896デフォルトの名無しさん2014/06/25(水) 20:40:07.79ID:IVQPbhSw
>>894
ありがとうございます。
試してみます。
もうひとつ質問なのですが、列のうちある値を超えた時の最小の行番地をかえしてほしいとき、
min(if(a1:a100)>x,rows(a1:a100)とやったらうまくいきません。どうすればよいのでしょうか。前で来たのですがうろ覚えなせいかできません。
08978942014/06/25(水) 20:40:17.63ID:vwnOk3e3
あゴメン Excelに NaNっていうエラー値なかった
エラーって言葉で勘違いしてた
>>894は無視して
0898デフォルトの名無しさん2014/06/25(水) 20:41:09.47ID:IVQPbhSw
>>896
すみません、うまくいきました
0899デフォルトの名無しさん2014/06/25(水) 21:00:15.35ID:LGqGwfyW
>>895
しらべるというのは最終行を取得したあと
繰り返して調べてもし値があれば更新していくと考えて、
do isnumeric(cells(lastrow,1)=false then
lastrow=lastrow-1
elseif exit
loop
とすればよいのでしょうか?いまいちよく分からないです
0900デフォルトの名無しさん2014/06/25(水) 21:15:40.33ID:37/MdzoU
>>893
コード書いてみた
以下のマクロを実行すると変数colで指定した列の最終行が変数rwに入る
例によってシートはWith〜で指定しているので適宜書き換えてください。

Sub test()
Dim col As Long   '処理対象列
Dim rw As Long   '最終行
Dim er As String  '検索するエラー値
Dim rng As Range
With ThisWorkbook.Sheets(1) '処理対象シートの指定
 col = 1   '1列目を指定
 er = "NaN"  'エラー値”NaN"を設定
 rw = .Cells(.Rows.Count, col).End(xlUp).Row
 If .Cells(rw, col).Value = er Then
  Set rng = .Cells(1, col).Resize(rw).Find(What:=er, after:=.Cells(rw, col), _
  LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, _
  SearchDirection:=xlNext, MatchCase:=True, MatchByte:=True)
  rw = rng.Row - 1
 End If
 Set rng = Nothing
End With
End Sub
0901デフォルトの名無しさん2014/06/25(水) 21:19:26.53ID:5r4HS54B
>>899

for 探索行 = 見つかった行 to 1 step -1
if 数値かどうか and エラーでは無い とか then
目的の行 = 探索行
exit for
endif
next
0902デフォルトの名無しさん2014/06/25(水) 21:24:00.62ID:5r4HS54B
エラーが全く無いとか、エラーが2回以上続くとか、そういうのに対応するなら工夫がいる
エラーならフラグをたてて、エラーじゃなくなるまで探せばいい
0903デフォルトの名無しさん2014/06/25(水) 21:24:19.82ID:IMwLZcWP
>>899
エラーのセルは数字以外のデータ("NaN")だって前提で良いのか?

Dim lastgoodrow As Long
Dim i As Long

For i = lastrow To 1 Step -1
 If IsNumeric(.Cells(i, 1)) Then
  lastgoodrow = i
  Exit For
 End If
Next

こんな感じでいけるんじゃね
Do Loopでもやれなくはないけど
09049002014/06/25(水) 21:26:51.14ID:37/MdzoU
>>900はRange変数を使わなくても問題なかった。

Sub test()
Dim col As Long '処理対象列
Dim rw As Long '最終行
Dim er As String '検索するエラー値
With ThisWorkbook.Sheets(1) '処理対象シートの指定
col = 1 '1列目を指定
er = "NaN" 'エラー値”NaN"を設定
rw = .Cells(.Rows.Count, col).End(xlUp).Row
If .Cells(rw, col).Value = er Then
rw = .Cells(1, col).Resize(rw).Find(What:=er, after:=.Cells(rw, col), _
LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=True, MatchByte:=True).Row - 1
End If
End With
End Sub

ただし、使わないと可読性は下がるかもしれない。
09059002014/06/25(水) 21:31:27.09ID:37/MdzoU
エクセルが吐く本来のエラーじゃなくて、
>>893が独自に"NaN"という文字列をエラーとして定義しているだけじゃないの?
エラー以外が数値かどうかもはっきりしないから
それ前提で>>900のコード書いたんだけど。
0906デフォルトの名無しさん2014/06/25(水) 21:41:08.62ID:5r4HS54B
良く読んでなかった、こうだな

LastGoodRow = -1

If Cells(LastRow,1) <> "NaN" Then
 LastGoodRow = LastRow
Else
 For i = LastRow To 1 Step -1
  If Cells(i, 1) <> "NaN" Then
   LastGoodRow = i
   Exit For
  End If
 Next
End If

if LastGoodRow = -1 Then
 MsgBox "全部エラーだって、信じらんない"
End If
0907>>8992014/06/25(水) 21:45:00.34ID:2Yp71LFs
>>901,>>902,>>903,>>904,>>905,>>906ありがとうございます。
>>905のおっしゃる通りNaNというのは私が出力プログラム側で設定したエラーメッセージです。


参考にして下記のコードで試したところうまくいきました。1 step -1という意味が調べても出てきませんが、ウォッチしていくと思い通りの動きをしてくれるのでこれで良いと思います。とても助かりました。

for i = lastrow to 1 step -1
if cells(lastrow,1).value=″NaN″ then lastrow=lastrow-1
else exit for
end if
next i

すべてメモ帳に保存して勉強します。とても参考になりました。
0908デフォルトの名無しさん2014/06/25(水) 22:14:38.62ID:37/MdzoU
>>907
1 step -1 っていうふうに区切っちゃ駄目。
あくまでも
For i = A to B step C
という構文の一部だからね。

変数iをカウンターとして、Aがその開始値でBが終了値、
Cは、ループするときの数値の増減を指定するものだよ。
デフォルトは1だからループ一回ごとにカウンターが1ずつ増える。
Stepを-1にすればループするごとにiの値が1ずつ減る。

今回はそれを利用して判定する行をひとつずつ上にずらしてるんだよ。
下から上に1行ずつセルの値が"NaN" かどうかを判定して、
初めて"NaN" じゃなかった行を取得してる。

ちなみに俺の書いたコードではFindを使って上から下に検索し、
初めて”NaN"が出てくる行(の一個上の行)を取得してました。
0909デフォルトの名無しさん2014/06/25(水) 22:24:54.50ID:WuPundp1
>>908
>ちなみに俺の書いたコードではFindを使って上から下に検索し、
>初めて”NaN"が出てくる行(の一個上の行)を取得してました。

目的からすると下から上にNaN以外を探した方がベターなんじゃない
0910デフォルトの名無しさん2014/06/25(水) 22:50:03.47ID:37/MdzoU
>>909
データの総数とエラー値の個数がわからないからなんとも言えないんじゃないですか?
データが10万行有って、そのうちつかえるデータが100行ほどで
残りが全部NaNだった、なんて場合は上からのほうが早いですし。
まぁ、そんな極端な事例があるかどうかは知りませんが。

あと、一行ずつループで判定するよりは
ざっくりFindで検索のほうが分かりやすいかなと。
レス数が900を超えています。1000を超えると表示できなくなるよ。