X



Excel VBA 質問スレ Part49©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん 転載ダメ©2ch.net (ワッチョイ bb2e-8SzA)
垢版 |
2017/06/26(月) 02:15:14.60ID:T3ylemnb0
!extend:checked:vvvvv:1000:512
!extend:checked:vvvvv:1000:512

スレ立ての際は一行目に
!extend:checked:vvvvv:1000:512
と入れてスレ立てして下さい

ExcelのVBAに関する質問スレです
コード書き込みや作成依頼もOK

※前スレ
Excel VBA 質問スレ Part48
http://mevius.2ch.net/test/read.cgi/tech/1494890685/

※関連スレ
VBAなんでも質問スレ Part2
http://mevius.2ch.net/test/read.cgi/tech/1432173164/
Access VBA 質問スレ Part1
http://mevius.2ch.net/test/read.cgi/tech/1328536426/
Excel総合相談所 126
https://mevius.2ch.net/test/read.cgi/bsoft/1496487719/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured
0301デフォルトの名無しさん (オッペケ Srd7-Ucbr)
垢版 |
2017/07/17(月) 20:12:26.22ID:7pjXcMGRr
馬鹿の一つ覚えみたいに、なんでもかんでも変数に入れちゃうし、しかもいまだにハンガリアン記法だったりする。
エラー対策もバッチリですと言わんばかりにエラー処理が延々と続くコードを晒す。
ただでさえ冗長な言語なのに輪をかけて冗長なコードを書く。
誰もお前のコードなんかコピペしねーからコアな部分だけを簡潔にかけ、と言いたくなる。
VBAが書けるぐらいでエンジニアづらするな。
0309デフォルトの名無しさん (ワッチョイ ef11-+gV6)
垢版 |
2017/07/17(月) 20:54:22.06ID:ZHV5JA270
エンジニアかどうかってプログラム言語に依存する概念だっけ?
実現手段なんかコロコロ変わるのに
0314デフォルトの名無しさん (ワッチョイ 5ce3-z+eH)
垢版 |
2017/07/17(月) 21:38:42.01ID:xDa7p7Qa0
ExcelVBAの挙動が謎すぎて困る
IF xx IS NOT NULL AND xx.value = 100
みたいので例外出たときは目を疑った

nullのときも両辺評価するって決まってるならまだしも
普段は何事もなく動いてるのに
急に気まぐれに両方評価するのやめーや…
0330デフォルトの名無しさん (スッップ Sd70-QKFr)
垢版 |
2017/07/18(火) 00:17:38.11ID:kpygt+jXd
nullの話出たから聞きたいんだけどnullとかnothingの判定を完結にやるいい方法ってないの?
やりたいのはnull,vbnull,nothing,emptyなどなど値が入ってない状態を検知したい

全部if elseifでやるのは汚すぎるからあまりやりたくない
0331デフォルトの名無しさん (ワッチョイ f191-+gV6)
垢版 |
2017/07/18(火) 00:18:33.82ID:sD2l3tVa0
>>330
全部調べる関数を作ればいいのでは?
0340デフォルトの名無しさん (オッペケ Srd7-Ucbr)
垢版 |
2017/07/18(火) 07:42:58.67ID:StSxL3ktr
こんな感じかな。

Function IsNone(hoge) as Boolean
  Select case True
    Case IsNull(hoge)
      IsNone = True
    Case IsEmpty(hoge)
      IsNone = True     
    Case hoge is Nothing
      IsNone = True
    Case hoge = ""
      IsNone = True
    Case hoge = vbnullstring
      IsNone = True
    Case Else
      IsNone = False
  End Select
End Function
0341デフォルトの名無しさん (オイコラミネオ MMb6-hcOc)
垢版 |
2017/07/18(火) 08:48:10.34ID:XjshxdE9M
なんでこんな初心者用のスレでVBAはゴミだのカスだのドヤ顔でほざいてるの?
どうせ普段は別の言語で仕事してる奴が、ちょっと頼まれたVBAが解らなくてファビョってるんだろ?w
0345デフォルトの名無しさん (オッペケ Sr39-nv+z)
垢版 |
2017/07/18(火) 12:19:29.42ID:1XJz7Xgqr
どうせ自称VBAに詳しいクズと自称メインは他言語のクズしかいないんだから仲良くしろよ
0349デフォルトの名無しさん (オッペケ Srd7-Ucbr)
垢版 |
2017/07/18(火) 20:30:12.85ID:StSxL3ktr
>>348
もちろん自由に使えばいいけど、スマホで書いてるのでPCテストしてない。自己責任でよろしく。

読み返したら、Is Nothing のところは明らかにエラーになると思うので、こんな感じのほうがいいかも。(PCテストしてないので自信はない。あしからず)

Function IsNone(hoge) as Boolean
  If IsObject(hoge) Then
    If hoge Is Nothing Then IsNone = True
  End If
  Select case True
    Case IsNull(hoge)
      IsNone = True
    Case IsEmpty(hoge)
      IsNone = True
    Case hoge = ""
      IsNone = True
    Case hoge = vbnullstring
      IsNone = True
    Case Else
      IsNone = False
  End Select
End Function

なんか美しくないね。
ま、好きなように書き換えて。
0352デフォルトの名無しさん (ワッチョイ 974b-+vhE)
垢版 |
2017/07/18(火) 21:12:18.15ID:FECT5IdT0
>>349
objectを掴めてないときのemptyとか、開放できないときのオートメーションエラーとかに悩まされて、ある程度解決してたんですが、これで最終解脱できそうな予感。
ありがたや。
0353デフォルトの名無しさん (ワッチョイ 6fea-N0vF)
垢版 |
2017/07/18(火) 21:59:56.82ID:jNcdEVA90
ExcelからOutlookを起動し、予定表から会議依頼を作成するマクロを作成しています
あらかた思っていたものは作れたのですが、自分の予定表ではなく共有の予定表に保存する場合のコードがさっぱり分かりません
共有の予定表での作成方法をご教示頂けますでしょうか
0355デフォルトの名無しさん (オッペケ Srd7-Ucbr)
垢版 |
2017/07/19(水) 00:59:23.29ID:r34rJ2pSr
>>354
おっしゃるとおり。
あるいは、Select以下をElseでつなげるか。

でも美しくないので書き換えてみた。
結構いいんじゃね?(軽くテスト済み)

結局、>>333 が最適解だったわけね。
なかなかの実力者とみた。

Function IsNone(hoge) As Boolean
  Select Case VarType(hoge)
    Case vbEmpty, vbNull
      IsNone = True
    Case vbObject
      If hoge Is Nothing Then IsNone = True
    Case vbString
      If hoge = vbNullString Or hoge = "" Then IsNone = True
    Case Else
      IsNone = False
  End Select
End Function
0356デフォルトの名無しさん (ワッチョイ f191-+gV6)
垢版 |
2017/07/19(水) 02:45:10.33ID:3ENxF81t0
>>355
isNoneが未定になるパスがあるんじゃね
0358デフォルトの名無しさん (ワッチョイ 974b-+vhE)
垢版 |
2017/07/19(水) 05:14:51.84ID:uwa7S77b0
>>355
Sub buf()
On Error Resume Next
For i = 1 to n
Set MyObj = SPAM
If Err then
If not IsNone(SPAM) then Brake
Else
Goto Continue
End if
Else
ここで処理。
Continue:
Err.clear
Set MyObj = Nothing
End if
Next
End sub

みたいな使い方を考えたんですが、全然美しくない・・・
どうすれば良いでしょうか。
0364デフォルトの名無しさん (ワッチョイ 4b3d-1CH6)
垢版 |
2017/07/19(水) 12:01:18.52ID:pHR1WedN0
どういうものを実装するかにもよるけど経験から言うと配列の判定は別の方がいい。
アプローチの仕方が違うから、変数単体で認識させていたものを配列突っ込める様にした時なんかにバグの温床になる。
0367デフォルトの名無しさん (オッペケ Sr5f-nv+z)
垢版 |
2017/07/19(水) 12:28:40.18ID:oLf4rjVBr
variant型は脊髄反射で否定するくせにvariantみたいなヤリマン関数が大好きなお前らってw
0369デフォルトの名無しさん (ワッチョイ 4b3d-1CH6)
垢版 |
2017/07/19(水) 14:51:31.77ID:pHR1WedN0
前スレかその前かの最後の方でVariant型絶対使わないマン出てきていた様な気がするけど。

そういう信条自体は別に良いんだけど、Variant型使えば解決出来る事を信条のせいで解決出来ず、
その結果として「VBAは欠陥」って言い出す変な人はこのスレでよく見かける。
0373デフォルトの名無しさん (オッペケ Srd7-Ucbr)
垢版 |
2017/07/19(水) 18:31:39.20ID:r34rJ2pSr
>>364-365
配列は要素数の空判定でお茶を濁そう。

これ以上のブラッシュアップは断念。
コードとしてはそこそこ美しいと思う。

Function IsNone(hoge) As Boolean
  Select Case VarType(hoge)
    Case vbEmpty
      IsNone = True
    Case vbNull
      IsNone = True
    Case vbObject
      If hoge Is Nothing Then IsNone = True
    Case vbString
      If hoge = vbNullString Or hoge = "" Then IsNone = True
    Case vbArray + vbVariant
      If Ubound(hoge) = -1 Then IsNone = False
  End Select
End Function
0374デフォルトの名無しさん (オッペケ Srd7-Ucbr)
垢版 |
2017/07/19(水) 18:35:56.55ID:r34rJ2pSr
訂正。最後、Trueだった。。(^_^;)

Function IsNone(hoge) As Boolean
  Select Case VarType(hoge)
    Case vbEmpty
      IsNone = True
    Case vbNull
      IsNone = True
    Case vbObject
      If hoge Is Nothing Then IsNone = True
    Case vbString
      If hoge = vbNullString Or hoge = "" Then IsNone = True
    Case vbArray + vbVariant
      If Ubound(hoge) = -1 Then IsNone = True
  End Select
End Function
0375デフォルトの名無しさん (ワッチョイ 4b3d-1CH6)
垢版 |
2017/07/19(水) 18:47:58.49ID:pHR1WedN0
>>373
Function IsNone(hoge) As Boolean
  Select Case VarType(hoge)
    Case vbEmpty,vbNull
      IsNone = True
    Case vbObject
      If hoge Is Nothing Then IsNone = True
    Case vbString
      If Len(Trim(hoge)) = 0 Then IsNone = True
    Case Is >= vbArray
      IsNone = True
  End Select
End Function

ArrayはVariant型以外の場合もあるから、この方がいい。
0384デフォルトの名無しさん (ワッチョイ 4b3d-1CH6)
垢版 |
2017/07/19(水) 20:28:12.28ID:pHR1WedN0
>>382
うろ覚えだけどVarTypeでvbArrayとして返ってきた場合でもUboundするとエラーになるケースがあったはずなので、
Uboundを使う場合は別関数でOn Error Gotoで飛ばせるようにしておきたい。

Function SafeUBound(hoge, Optional div As Long) As Long
On Error GoTo fin
If div = 0 Then div = 1
SafeUBound = -1
SafeUBound = UBound(hoge, div)
fin:
End Function

Function SafeLBound(hoge, Optional div As Long) As Long
On Error GoTo fin
If div = 0 Then div = 1
SafeLBound = 0
SafeLBound = LBound(hoge, div)
fin:
End Function

と置いてSafeUbound < SafeLBoundで判定したい。
0385デフォルトの名無しさん (オッペケ Srd7-Ucbr)
垢版 |
2017/07/19(水) 20:38:22.51ID:r34rJ2pSr
一応簡単なテストコード的な…

hoge = Range("A1").Value: Debug.Print IsNone(hoge) & ":" & VarType(hoge)
hoge = InputBox("値を入力してください。"): Debug.Print IsNone(hoge) & ":" & VarType(hoge)
Set hoge = Sheets(1): Debug.Print IsNone(hoge) & ":" & VarType(hoge)
Set hoge = Nothing: Debug.Print IsNone(hoge) & ":" & VarType(hoge)
Set hoge = CreateObject("InternetExplorer.Application"): Debug.Print IsNone(hoge) & ":" & VarType(hoge)
hoge.Quit
Set hoge = Nothing: Debug.Print IsNone(hoge) & ":" & VarType(hoge)
hoge = Array(): Debug.Print IsNone(hoge) & ":" & VarType(hoge)
0391デフォルトの名無しさん (ワッチョイ f191-+gV6)
垢版 |
2017/07/19(水) 23:08:15.46ID:3ENxF81t0
>>386
無い
作れば?
0393デフォルトの名無しさん (ワッチョイ 4b3d-1CH6)
垢版 |
2017/07/19(水) 23:39:04.83ID:pHR1WedN0
>>392
ああ、やっぱりそういう方法しかないのね。

元々がIf文を可能な限り使わないというところから出発しているし、
それだとIf Else使った方が処理も速いしSelect文で読みやすくするっていう利点も潰してるんだよな。
0395デフォルトの名無しさん (オッペケ Sr1b-QbI6)
垢版 |
2017/07/20(木) 01:36:37.21ID:IzREkzShr
やはり、配列の空判定は別関数にしたほうが良さそうだね。

Function IsNone(hoge) As Boolean
  Select Case VarType(hoge)
    Case vbEmpty, vbNull
      IsNone = True
    Case vbObject
      If hoge Is Nothing Then IsNone = True
    Case vbString
      If Len(Trim(hoge)) = 0 Then IsNone = True
    Case Is >= vbArray
      If ArrayEmpty(hoge) Then IsNone = True
  End Select
End Function

Function ArrayEmpty(hoge) As Boolean
  美しいコード
End Function
0396デフォルトの名無しさん (オッペケ Sr1b-QbI6)
垢版 |
2017/07/20(木) 01:50:57.43ID:IzREkzShr
>>384を使って、

Function ArrayEmpty(hoge) As Boolean
  If SafeUbound < SafeLBound Then ArrayEmpty = True
End Function

Function SafeUBound(hoge, Optional div As Long) As Long
On Error GoTo fin
If div = 0 Then div = 1
SafeUBound = -1
SafeUBound = UBound(hoge, div)
fin:
End Function

Function SafeLBound(hoge, Optional div As Long) As Long
On Error GoTo fin
If div = 0 Then div = 1
SafeLBound = 0
SafeLBound = LBound(hoge, div)
fin:
End Function

う〜〜ん、、、いまいち美しくない…orz
0397デフォルトの名無しさん (オッペケ Sr1b-QbI6)
垢版 |
2017/07/20(木) 02:11:18.92ID:IzREkzShr
>>394
> 単に空チェックだけなら

Len(Trim(hoge)) = 0

で事足りてるような気はする。

イミディエイトウィンドウでテストしてみて。

? Len(Trim(InputBox("値を入力してね"))) = 0

[OK][キャンセル]どちらでも True が返る。
0398デフォルトの名無しさん (ワッチョイ 473d-pqVL)
垢版 |
2017/07/20(木) 02:46:26.38ID:2lo8GEfG0
>>396
Function RBound(hoge, Optional div As Long) As Long
On Error Resume Next
If div = 0 Then div = 1
RBound = UBound(hoge, div) - LBound(hoge, div) + 1
End Function

あくまで配列要素数があるかどうかだけ判断したいなら、こういう関数でもいいと思うけど。
0399デフォルトの名無しさん (オッペケ Sr1b-QbI6)
垢版 |
2017/07/20(木) 07:38:01.83ID:IzREkzShr
>>398
おおー、だいぶスッキリしたね。

ひとつ残念なのは、引数の次元指定が美しくないんだよなー。

つか、1次元の要素が空の配列なんて使う?
1次元が空かどうかだけ判定すればいいんじゃね?
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況