位置情報で子どもの居場所をお知らせ

ProgressBarを用いる場合、全体の処理数を求めますが、Do Loopを用いる場合、For文と異なり必ずしもすぐに全処理数が分かるわけではありません。そのような場合、どのように全処理数を求めればよいですか?

私は、あるフォルダにあるファイルすべてを処理するプログラムを作りました。Do Loopで全てのファイルを参照し終わるまでをUntilの条件としています。したがって、いくつのファイルがあるかは分かりません。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

#2です。


>ファイル数の合計で結構です。ちょっと甘えていますが、先ほどのご回答のどこを改造すればよいのかがわかりません
Private Sub test02()
Dim fn As String
Dim hn As String
p01:
fn = InputBox("フォルダ名=", "フォルダ指定", "c:\My Documents\")
i = 1
sdirname = Dir(fn)
Do While sdirname <> ""

i = i + 1

'------
sdirname = Dir
Loop
MsgBox i & " 個のファイルあり"
End Sub
でやって見てください。
ファイル数やレコード数が取得できる、VBのプロパテイかメソッドがない場合は自分でそれらの数を算出し、変数にセットしないとなりません。プログレスバーを使うルーチンに入る前に。
これも1ファイルや1レコード当たりの処理時間が等しいと(違いは無視できると)言う前提で、全体300のうち60番目の処理をしている時は20%進行済みと表示すると言うことだと思います。
    • good
    • 0

>ProgressBarを用いる場合、全体の処理数を求めますが、>Do Loopを用いる場合、For文と異なり必ずしもすぐに


>全処理数が分かるわけではありません。そのような場合、
>どのように全処理数を求めればよいですか?

通常は、件数がわからないものにプログレスバーは使いません。というか、使えません。
なので、事前に処理件数が大雑把でもわかる必要があります。
もちろん、さまざまな処理に対して全処理数を求める汎用的な方法はありません。


>私は、あるフォルダにあるファイルすべてを処理する
>プログラムを作りました。Do Loopで全てのファイルを
>参照し終わるまでをUntilの条件としています。
>したがって、いくつのファイルがあるかは分かりません。

で、件数を取得する方法ですが、やっぱりDirで取ってくるしかないのでは?
件数を取得するだけの処理を作るのもなんだかと思いますが、プログレスバーを使いたいのでしたらしょうがないと思ってください。
    • good
    • 0

#1です。


あるフォルダの中のファイル数は#1を少し改造すると出ますのでそれの参考に上げたまでです。
>あくまでProgressBar表示のための全処理数を知りたいのですが
ProgressBarは汎用的なものです。例えば処理時間の経過を表す場合は、処理完了予定時間の合計は判らないことが多いと思います。だから何をもって、処理時間に関係付けるかではないのでしょうか。この質問では何を知りたいのでしょうか。推定するに、例えばファイル数でなければ、フォルダ内の通しのレコード数合計ですか。
これももし見当違いの場合はお許し下さい。

この回答への補足

有難う御座います。まだ不慣れでうまくお伝えすることができず申し訳御座いません。

ファイル数の合計で結構です。ちょっと甘えていますが、先ほどのご回答のどこを改造すればよいのかがわかりません。Do Loopでご説明通りDir関数を用いてみつけたファイルを全て処理するプログラムを作りました。私なりに考えるのは、Do Loop内で何回の処理が行われたかをカウントすることでのみ、その処理数、つまりファイル総数が求められるということで、ProgressBar作成のためDo loop以前に処理数を知ることはできないのではと考えます。やはり、はじめにDir関数を使いファイルの総数を数えるためのコードが新たに必要なのでしょうか?

補足日時:2004/04/16 00:06
    • good
    • 0

他の質問の回答に使ったものですが(但しエクセルVBA)


Private Sub test01()
Dim fn As String
Dim hn As String
p01:
fn = InputBox("フォルダ名=", "フォルダ指定", "c:\My Documents\")
If fn = "end" Then Exit Sub
' fn = "c:\My Documents\"
i = 2
sdirname = Dir(fn)
Do While sdirname <> ""
If Right(sdirname, 4) = ".csv" Then
Cells(i, 1) = sdirname
hn = fn & sdirname
Cells(i, 2) = hn
i = i + 1
End If
'------
sdirname = Dir
Loop
GoTo p01
End Sub
の「Do While sdirname <> ""」の部分が参考になりませんか。
もし見当違いの場合はお許し下さい。

この回答への補足

有難う御座います。しかし、あくまでProgressBar表示のための全処理数を知りたいのですが。もし、お分かりになれば宜しくお願い致します。

補足日時:2004/04/15 23:26
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qexcel VBA プログレスバーについて(初心者)

VBA初心者の質問です…
excelで入力されている値を用いて、グラフ作成する簡単なデータを作りました。
特に問題なくグラフは出来たのですが、グラフ作成が1つではなく数個同時(順番)に作成しているため時間が掛かってしまいます。
この処理中にプログレスバーを表示出来ればと思い質問を致します。

私なりに調べ(goo内)下記サンプルを発見し、簡単なのでこれを使をうかと思うのですが、UserForm1の処理前にUserForm2.showだけでは
UserForm2の処理が終わらないと処理をしません…当然ですよね…
本当に初心者で申し訳ないのですが、UserForm1の処理最中にUserform2のプログレスバーを表示するのにはどうすればいいのでしょうか…

【サンプル】
Private Sub UserForm_Activate()

With Label1
.SpecialEffect = 2
.BackColor = vbBlue
www = .Width
.Width = 0
End With

For i = 1 To 1000
Me.Caption = i
Label1.Width = i / 1000 * www
Me.Repaint
Next

End Sub

また他におすすめなやり方があれば教えて頂ければ…
初心者な質問で申し訳御座いません。

VBA初心者の質問です…
excelで入力されている値を用いて、グラフ作成する簡単なデータを作りました。
特に問題なくグラフは出来たのですが、グラフ作成が1つではなく数個同時(順番)に作成しているため時間が掛かってしまいます。
この処理中にプログレスバーを表示出来ればと思い質問を致します。

私なりに調べ(goo内)下記サンプルを発見し、簡単なのでこれを使をうかと思うのですが、UserForm1の処理前にUserForm2.showだけでは
UserForm2の処理が終わらないと処理をしません…当然ですよね…
本当に初...続きを読む

Aベストアンサー

いいえ
☆下記のループに、入れては、だめです。
For j = 1 To 10000
Next
は、削除するか コメント行にしてください。


' ----------------------------------------------------
For j = 1 To 10000
'デバッグ用タイミング(実際はここに実行マクロを入れる)
↑↑
ここの部分に私で言うグラフ作成マクロを組み込めばいいのでしょうか?

Next
'-----------------------------------------------------
☆正確には、下記の中です。



' ----------------------------------------------------
'(実際はここに実行マクロを入れる)
' 例えば、
  Call グラフ作成処理プログラム
' とします。
'-----------------------------------------------------

また、
For i = 1 To cend
j = i / cend * 100
With UserForm1
.Label2.Caption = Int(j) & "%"
.Label1.Width = tsiz * j / 100
End With

の中の、cend = 1500 'デバッグ用数値を独自に設定する必要があるでしょう。
例えば、処理時間が、プログレスバーの最後にならない内に処理が終わってしまうとか、その反対にプログレスバーが、早く終わってしまうとかです。

私の場合は、処理する セルの数を算出して 設定しています。
参考として、変形させた コードを乗せます。
詳しいことは、省略します。[ ご自分で、考えてください。 ]


' 以下は 標準モジュールです。
Sub 123()
Dim tsiz As Integer, K As Integer, N As Integer
Dim Memorys As Long, Memorys_Cunt As Long, Memoryss As Long


Do
' 実際はここに実行マクロを入れる) 

Call My_Progress_bar(Memorys_Cunt, RoW, Memoryss)
Loop

UserForm1.Hide

End Sub


Function My_Progress_bar(I As Long, tsiz As Integer, cend As Long)

Dim J As Integer



J = I / cend * 100
If J >= 100 Then J = 100

With UserForm2
.Label2.Caption = Int(J) & "%"
.Label1.Width = tsiz * J / 100
End With

DoEvents

End Function
UserForm1.Show vbModeless


注意:これは、VBA には、プログレスバーの機能(コマンド)が、ないので、プログレスバー風に考えられたものです。

いいえ
☆下記のループに、入れては、だめです。
For j = 1 To 10000
Next
は、削除するか コメント行にしてください。


' ----------------------------------------------------
For j = 1 To 10000
'デバッグ用タイミング(実際はここに実行マクロを入れる)
↑↑
ここの部分に私で言うグラフ作成マクロを組み込めばいいのでしょうか?

Next
'-----------------------------------------------------
☆正確には、下記の中です。



' ----------------------------------------------------...続きを読む

QDoEvents関数って何?

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら

for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。

しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」

と書いてあるのですが正直、書いてあることがよくわかりません。

どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?

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

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そ...続きを読む

Aベストアンサー

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
    DoEvents
    Cells(i,1) = ""
  Next i
End Sub

Private Sub CommandButton2_Click()
  MsgBox "hoge"
End Sub

っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。

これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。

Private Canceled As Boolean

Private Sub CommandButton1_Click()

  CommandButton2.Enabled = False

  Dim i As Long
  For i = 1 To 50000
    DoEvents

    If Canceled = True Then
      MsgBox "キャンセルしました"
      Exit Sub
    End If

    Cells(i, 1).Value = ""
  Next i
End Sub

Private CommandButton2_Click()
  Canceled = True
End Sub



コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
...続きを読む

Qエクセルマクロで進捗状況を表示させたい

いつもお世話になります。こんなことできますか?

プログラムの進捗状況を表示させたいのですが、
ステータスバーの表示だと隅っこの方ですし、表示も小さいので、画面の真ん中にメッセージウィンドウを出せないかななんて考えてます。
進捗状況は刻々と変わるので、Msgboxだといちいち「OK」を押さないといけなくなり実用的ではありません。

画面真ん中に表示する方法、何かいい方法ありませんか。

Aベストアンサー

ステータスバーに表示させるにが一番簡単な方法なのですが、お気に召さないのであればその次に簡単な方法を。

1.現在のシートとは別に表示用のシートを作成します。
2.表示用のシートのまんなかあたりのセルに、ステータスバーに表示させる進捗状況をセットします。
3.マクロ作動中は常に表示用シートをアクティブにして見せておくようにします。

これでOKですね。

Qエクセル VBA ユーザーフォームを閉じる

ユーザーフォームを開く時は
UserForm1.Showですが
閉じる時は?
UserForm1.Close
だとコンパイルエラーになります。
End
にするしかないですか?

Aベストアンサー

Unload Me とか Unload UserForm1 でユーザーフォームを閉じることができます。

Qある範囲のセルから任意の値を検索して、その隣のセルの値を取得するという関数はありますか?

Excelの関数について質問します。
ある範囲のせるを検索して、その隣のセルの値を取得するという関数を探しています。
なければユーザー定義で作りたいと思っています。
VLOOKUP関数では一番左端が検索されますが、
それをある範囲まで拡張して、
その右隣の値を取得できるようにしたいのです。
どうかお知恵をお貸しください。

Aベストアンサー

●X1セルの値を範囲A1:F200の中から探して、その右隣のセルの値を返す

 =OFFSET(A1,SUMPRODUCT(ROW(A1:F200)*(A1:F200=X1))-1,SUMPRODUCT(COLUMN(A1:F200)*(A1:F200=X1)))

※最初のA1はワークシートの左上隅を示すものなので、検索範囲に関わらずA1固定
※SUMPRODUCT(ROW(A1:F200)*(A1:F200=X1)) ⇒ A1:F200で値がX1と一致するセルの行番号

>その「ある範囲」の中には検索したい値が入っているセルは1つしかありません。
というのが前提です。複数のセルがHITすると関係ないセルの値が返るので、
場合によっては、IFをかぶせてCOUNTIFで確認した方が良いかもしれません。
 ex. =IF(COUNTIF(A1:F200,X1)=1,【上記数式】,"えらー")

ちなみに、VBAでやるならこんな感じになるかと。

動作の概要
 【検査範囲】から【検査値】を探し、
 最初にHITしたセルについて、右隣のセルの値を返す。
 ex. =Sample(X1,A1:F200)

'--------------------------↓ココカラ↓--------------------------
Function Sample(ByVal 検査値 As Variant,ByVal 検査範囲 As Range)
 For Each セル In 検査範囲
  If セル = 検査値 Then Exit For
 Next セル
 Sample = セル.Offset(0, 1)
End Function
'--------------------------↑ココマデ↑--------------------------

いずれもExcel2003で動作確認済。
以上ご参考まで。

●X1セルの値を範囲A1:F200の中から探して、その右隣のセルの値を返す

 =OFFSET(A1,SUMPRODUCT(ROW(A1:F200)*(A1:F200=X1))-1,SUMPRODUCT(COLUMN(A1:F200)*(A1:F200=X1)))

※最初のA1はワークシートの左上隅を示すものなので、検索範囲に関わらずA1固定
※SUMPRODUCT(ROW(A1:F200)*(A1:F200=X1)) ⇒ A1:F200で値がX1と一致するセルの行番号

>その「ある範囲」の中には検索したい値が入っているセルは1つしかありません。
というのが前提です。複数のセルがHITすると関係ないセルの値が返るので、
場...続きを読む

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

Qマクロ実行時、ユーザーフォームにラベルのテキストが表示されません。

エクセル2003VBAで、マクロ実行時にユーザーフォームを
モードレス表示して、そのユーザーフォームにラベル「マクロ実行中です・・・」を貼り付けています。
しかし、処理が追いついていないのか、そのラベルが表示されません。
ユーザーフォームにはコードを記述していません。コードは以下のみです。
UserForm1.Show vbModeless

テキストをTrueにしてからマクロ処理のようなコードがあるのでしょうか?
お手数をおかけしますが、解決方法をご存知の方よろしくお願いいたします。

Aベストアンサー

こんにちは。

>モードレス表示して、そのユーザーフォームにラベル「マクロ実行中です・・・」を貼り付けています。

ラベルをどう処理しているのか、まったく書いていないわけで、さっはり意味が分かりません。

UserForm が立ち上がっている状態では、「マクロ実行中」とは言えるかもしれませんが、表示する意味はないはずです。

Private Sub UserForm_Initialize()
 Label1.Caption = "マクロ実行中です....."
End Sub

必要ないと思います。
たとえば、ループした場合は以下のようにします。

Private Sub CommandButton1_Click()
  Dim i As Long
  Label1.Caption = "マクロ実行中です....."
  DoEvents 'これを入れないと表示しない。
  Do: i = i + 1: Loop Until i > 10 ^ 7
  Label1.Caption = "終了"
End Sub

3~4秒で終了するはずですが、一旦、何かVBAをあらかじめ動かして、オブジェクトが活性化しないと、それ以上に時間が掛かる可能性があります。

なお、この仕様は、Office VBA独特のようです。

こんにちは。

>モードレス表示して、そのユーザーフォームにラベル「マクロ実行中です・・・」を貼り付けています。

ラベルをどう処理しているのか、まったく書いていないわけで、さっはり意味が分かりません。

UserForm が立ち上がっている状態では、「マクロ実行中」とは言えるかもしれませんが、表示する意味はないはずです。

Private Sub UserForm_Initialize()
 Label1.Caption = "マクロ実行中です....."
End Sub

必要ないと思います。
たとえば、ループした場合は以下のようにします。
...続きを読む

QExcel2010でProgress bar

Excel2010を使っています
Progress barをツールボックスに追加したいのですが、コントロールの追加-利用可能なコントロールに出てきません

どこにあるのか教えて頂けますか?

Aベストアンサー

64bit版Officeでは(ProgressBar)ComCtrlは使えないと思います。
http://office.microsoft.com/ja-jp/word-help/HA010369476.aspx#_Toc254341418
からの抜粋を以下に。
32 ビット版の Office だけが対応する機能 (64 ビット版の Office にはない機能)
ActiveX コントロール ライブラリ (ComCtl) このライブラリには、ソリューションの構築に使用される ActiveX コントロールが含まれており、Microsoft Office プログラムの Access、Excel、および Word で最もよく使用されます。

また、Office2013(試用版)64bit でも同様でした。
今後MS社の気が変わることは多分無いかと・・・

なので、64bit版をアンインストールして32bit版に入れ替えるか、
自前でProgressBarもどきを作成するか、の二択かと?

Q[初心者です]VBAで指定列からAを検索し、発見したら隣のセルに値0を入れるマクロ。

VBAで指定列からAを検索し、発見したら隣のセルに0を入れるマクロを組みたいのですが、組み方がVBA初心者の為わかりません。
(例)
L列に、A、B、C、D、E、Fとランダムに文字が入っていて、
文字Aを検索し、発見したら隣のI列に値0を入れるというマクロです。

Sub Search()
Dim A As String
Set A = Worksheets("Sheet1").Cells.Find("A")
If A Is Nothing Then
ActiveCell.Offset(0, 1).Value = 0

End If
End Sub
と過去の質問で考えてみたのですが、Aがあった時、、、、
とコードが書けないです。
大変困っているので、ご教授頂けないでしょうか?
出来れば、そのままマクロに出来るコードを教えて頂けないでしょうか?
宜しくお願い致します。

Aベストアンサー

こんばんは。

#3さんのおっしゃっていることも、もっともなのですが、気になる点がありましたので、自分のことを踏まえて、書かせていただきます。

いずれ、また、同じようなケースが出会うと思います。こんな原則を考えてみたらどうでしょうか?それは、私も自身も同じなのですが、ワークシートのコマンドで行われるものは、記録マクロから作ってみるということです。他にも、「統合」とか、「置換」とか「オートフィルタ」「フィルタオプション」とかは、みんなパターンが決まっています。
その中の代表格が、この「Find」 です。

>Set A = Worksheets("Sheet1").Cells.Find("A")

>過去の質問で考えてみたのです

どうも、Find メソッドは、あるレベル以下の人は、省略する傾向があるようです。何が大事で、何が大事でないかというのは、やってみなければ分かりませんが、検索語だけを入れる書き方は、実務では、あまりしないほうがよいと思います。

だいたい、以下のTestFind2 ぐらいまでに、省略は、とどめたほうがよいです。

それは、Find は、必ずしも自分が思っているデフォルトとは違うことがあるので、「明示的(意図的に)」にオプションは入れたほうがよいです。
例えば、大文字小文字の違いを付けるなら、MatchCase:=True, 数式まで探すなら、LookIn:=xlFormulas

なお、Find メソッドは、5年経っても、たぶん完全に覚えられません。面倒なコードのひとつです。ですが、これはパターンが決まっているので、ひとつパターンが決まったら、それに当てはめればよいだけです。

#3さんで示されているMougのサンプルコードと似てはいるのですが、Mougのサンプルコードでは、Verionによって、失敗することがあります。

'--------------------------------------
'記録マクロをそのまま使う方法
Sub TestFind1()
Dim c As Range
 Set c = Columns("L:L").Find(What:="A", _
           After:=ActiveCell, _
           LookIn:=xlValues, _
           LookAt:=xlPart, _
           SearchOrder:=xlByRows, _
           SearchDirection:=xlNext, _
           MatchCase:=False, _
           MatchByte:=False, _
           SearchFormat:=False)
 c.Offset(0, 1).Value = 0
End Sub
'--------------------------------------
'TestFind1 をアレンジしてみる
Sub TestFind2()
Dim c As Range
'検索語
Const MYTXT As String = "A"
 Set c = ActiveSheet.Columns("L:L").Find(What:=MYTXT, _
           LookIn:=xlValues, _
           LookAt:=xlPart, _
           MatchCase:=False)
 If Not c Is Nothing Then
    c.Offset(0, 1).Value = 0
 End If
End Sub

'---------------------------------------
'複数ある場合(パターンを使った方法)
'---------------------------------------
Sub TestFind3()
  Dim c As Range
  Dim FirstAdd As String
  Const MYTXT As String = "A"
  Set c = ActiveSheet.Columns("L:L").Find( _
    What:=MYTXT, _
    LookIn:=xlValues, _
    LookAt:=xlPart, _
    MatchCase:=False)
  
  If Not c Is Nothing Then
    FirstAdd = c.Address
    Do
      c.Offset(, 1).Value = 0
      Set c = ActiveSheet.Columns("L:L").FindNext(c)
      If c.Address = FirstAdd Then Exit Sub
    Loop Until c Is Nothing
  End If
End Sub

こんばんは。

#3さんのおっしゃっていることも、もっともなのですが、気になる点がありましたので、自分のことを踏まえて、書かせていただきます。

いずれ、また、同じようなケースが出会うと思います。こんな原則を考えてみたらどうでしょうか?それは、私も自身も同じなのですが、ワークシートのコマンドで行われるものは、記録マクロから作ってみるということです。他にも、「統合」とか、「置換」とか「オートフィルタ」「フィルタオプション」とかは、みんなパターンが決まっています。
その中の代表...続きを読む

QVBAで別モジュールへの変数の受け渡し方法

初歩的な質問で申し訳ありません、
googleでもどのように検索してよいのかわからないので教えてください。


Userformにて作成したコード内にhogehogeという変数を宣言したとします。
これをPublic Sub CommandButton1_Click()内でhogehogeに文字列abcを代入します。

そしてcall を使ってmodule1の処理を行うのですが、
module1内で変数hogehogeに文字列abcが既に代入されているものとして
hogehogeを使いつつ、処理を続けるにはどのようにすればよいのでしょうか?

callで呼ぶ際に変数hogehogeの受け渡しなどが必要なのでしょうか?
(ちなみに全てPublic Subで書いております)

初心者なので質問がおかしいかもしれませんが
よろしくお願いします。

Aベストアンサー

標準的なコードの書き方があります。
具体的なコードがないので、こちらは想像の範囲なので、行き違いがあるのはご容赦願います。

>Userformにて作成したコード内にhogehogeという変数を宣言したとします。
変数を共有化(厳密にはグローバル化されていない、プロジェクト内のみ共有)するには、通常、「標準モジュール」で、プロシージャ外の変数は、Public変数になります。そして、明示的に、Public ○○と書きます。仮に、それが、UserFormモジュール内で使用されるものでも、標準モジュールに書くことになります。

>これをPublic Sub CommandButton1_Click()内でhogehogeに文字列abcを代入します。
そういう書き方は、本当に特殊な例を除いて書きません。Privateキーワードだけです。

つまり、ローカルモジュール(シートモジュール、ThisWorkbookモジュール、UserFormモジュール)には、Public キーワードは用いません。また、そこへのCallでの、呼び出しもしません。共有化させる場合は、一般的には「標準モジュール」を利用します。

しかし、別途、ユーザー定義関数やサブプロシージャで、引き数を参照渡し/値渡しで、変数の内容を渡すことがあります。この方が安定していますが、多少、コードの可読性が落ちます。

>callで呼ぶ際に変数hogehogeの受け渡しなどが必要なのでしょうか?
具体的にどのようなコードになっているか分かりませんし、Callでどう呼ぶのかは分かりませんが、引き数を設ければ、それはそれで済みます。

例:
'UserForm1 上 CommandButton1とTextBox1 を用意
'UserFormモジュール内
Private Sub CommandButton1_Click()
Dim a As Variant
  a = Val(TextBox1.Value)
 Call Test1Ref(a)
 MsgBox a
End Sub

'標準モジュール、そのままで参照渡しになっている
Public Sub Test1Ref(arg1 As Variant)
 arg1 = arg1 * 10
End Sub

ただし、この程度ならば、UserFormモジュール内で、Test1Refを置いても同じです。その時は、Publicキーワードは不要です。

標準的なコードの書き方があります。
具体的なコードがないので、こちらは想像の範囲なので、行き違いがあるのはご容赦願います。

>Userformにて作成したコード内にhogehogeという変数を宣言したとします。
変数を共有化(厳密にはグローバル化されていない、プロジェクト内のみ共有)するには、通常、「標準モジュール」で、プロシージャ外の変数は、Public変数になります。そして、明示的に、Public ○○と書きます。仮に、それが、UserFormモジュール内で使用されるものでも、標準モジュールに書くことになりま...続きを読む


人気Q&Aランキング