Static変数はファイルを一旦終了しないと0にリセットできないのでしょうか?
出来ないとすればStatic変数に代わりそういうことができる方法はありますか?(セルに番号を代入するのは無しで)

Sub 番号てすと()
Static g As Integer
MsgBox "今のG= " & g
g = g + 1
MsgBox "次のG= " & g
End Sub

A 回答 (7件)

>「同じ範囲内で宣言が重複しています」という「コンパイルエラー」がでました。


#5の方の言われる通りです。
変数の宣言は、普通最初にします。
宣言する前に使っているので、
自動的に宣言したことになり、
その後で、Staticの宣言があるので、
2度宣言していると解釈されます。
#4のサンプルは、ちょっと不親切だったかもしれません。
すみません。m(_ _)m
    • good
    • 0
この回答へのお礼

> #4のサンプルは、ちょっと不親切だったかもしれません。
> すみません。m(_ _)m

とんでもない!
そんなことも知らないわたしがお馬鹿なんですよ。

ありがとうございました。
以下でうまく行きました。
ただ、Sub aaa()からでないとSub 番号てすと(Optional reset As Boolean = False)が動かせないのですが(マクロの一覧に無くて)、どうしてでしょう?
何度も質問してすみません。

Sub 番号てすと(Optional reset As Boolean = False)
Static g As Integer
If (reset) Then g = 0: Exit Sub
MsgBox "今のG= " & g
g = g + 1
MsgBox "次のG= " & g
End Sub

Sub zzzzzzzz()
Call 番号てすと(reset:=True)
End Sub

Sub aaa()
Call 番号てすと
End Sub

お礼日時:2005/04/22 09:20

>Sub aaa()からでないとSub 番号てすと(Optional reset As Boolean = False)が動かせないのですが(マクロの一覧に無くて)、どうしてでしょう?


マクロの一覧には引数のあるSub(プロシジャー:手続き)は、表示されない様です。
一覧から選ぶだけなので、引数が指定できないからだと思います。(ちょっと余計なお世話なところもありますけど)
なので、現在やられているように、間接的に呼び出すようにして、メニューに表示するようにするしかないと思います。
    • good
    • 0
この回答へのお礼

よくわかりませんが、そうなんですか。
ありがとうございました。

お礼日時:2005/04/24 23:25

順序が違いますね。


Sub 番号てすと(Optional reset As Boolean = False)
Static g As Integer  ←最初に置く
 If (reset) Then g = 0
 MsgBox "今のG= " & g
 g = g + 1
 MsgBox "次のG= " & g
End Sub
    • good
    • 0
この回答へのお礼

ありがとうございました。
こんどは大丈夫でした。

でも、Sub 番号てすと(Optional reset As Boolean = False)
が、マクロの一覧に出てこないのはどうしてでしょう?

お礼日時:2005/04/22 09:11

関数の中に確保したstaticな変数は、関数の中だけで有効なので、外からリセットすることはできません。


なので、関数呼び出しの際に、変数の値によってリセットするようにすれば良いかも知れません。
Sub 番号てすと(Optional reset As Boolean = False)
If (reset) Then g = 0
通常の処理
end sub

call 番号てすと
の様に通常どおり呼び出した場合は、普通に実行されます。
call test(reset:=true)
リセットを指定して関数を呼び出すと、gを初期化してから通常の処理を実行します。

この回答への補足

Sub 番号てすと(Optional reset As Boolean = False)
If (reset) Then g = 0
Static g As Integer
MsgBox "今のG= " & g
g = g + 1
MsgBox "次のG= " & g
End Sub

Sub zzzzzzzz()
Call 番号てすと(reset:=True)
End Sub

「同じ範囲内で宣言が重複しています」という「コンパイルエラー」がでました。

補足日時:2005/04/21 15:12
    • good
    • 0

#1です。



であればグローバル変数にすればよいです。

モジュールの頭に、Static ではなく
Dim g As Integer
としてください。

私的にはどこでも書き換え可能なんてのはしませんが。

最悪でも、引数渡しにしますね。
    • good
    • 0
この回答へのお礼

グローバル変数ですか?!
また新しい呪文が出てきました・・・。

Static変数との違いがわかりました。ありがとうございます。

> 引数渡しにしますね。

引数渡しってどんなんでしょう?

お礼日時:2005/04/21 15:04

それは、Static 変数自体を使うことが違っているからです。


プロシージャ・レベルではなく、モジュールレベルで、変数を置き、

例:
Dim g As Integer
Sub 番号てすと()
 MsgBox "今のG= " & g
 g = g + 1
 MsgBox "次のG= " & g
End Sub

として、
例えば、
Sub HennsuClear()
 g = 0
End Sub

とします。
    • good
    • 0
この回答へのお礼

ありがとうございます。
おかげさまで解決いたしました。

モジュールレベルで、変数を置けるんですね。
勉強になりました。

お礼日時:2005/04/21 15:00

好きなときに、



g = 0

とすれば初期化できます。

この回答への補足

説明が足りませんでした。

Sub 番号てすと()
Static g As Integer
MsgBox "今のG= " & g
g = g + 1
MsgBox "次のG= " & g
End Sub

には触らずに、他のプロシージャからリセットしたいのです。

他のプロシージャに

Sub 番号クリア()
Static g As Integer
g = 0
End Sub

とやってもクリア出来なかったので・・・・。

補足日時:2005/04/21 13:26
    • good
    • 0

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

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

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

QExcelのVBA。public変数の値が消える

VBAについて。Excelの2003や2007を使っています。標準モジュールで public 変数を定義しました。 ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。全く同じマクロで、この現象が起こることと、起こらないことがあります。excelの2003でも2007でも、同じ現象が起こります。簡単なマクロで再現性のある具体的なものを示したいと思い、試しましたが、できませんでした。簡単なマクロでは、きちんとパブリック変数は保持されています。問題のあるマクロはかなり長いものなので、とても示せません。問題がどこにあるのかわかりません。このマクロで不都合があるという具体的なマクロを示すことができない状態での質問で、申し訳ありません。
また、このようなプログラミングをしていて思ったのですが、ユーザーフォームに対してユーザーが任意の引数を渡す方法あるいは、ユーザーフォームから引数を受け取る方法はあるのですか?今は、pubulic変数を用いたり、具体的なセルに値を代入したりしていますが、どう考えてもそれはエレガントではないし、汎用性もないと思います。引数で引き渡すのが一番綺麗でいいとは思うのですが、それが可能かどうかわかりません。

VBAについて。Excelの2003や2007を使っています。標準モジュールで public 変数を定義しました。 ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。全く同じマクロで、この現象が起こることと、起こらないことがあります。excelの2003でも2007でも、同じ現象が起こります。簡単なマクロで再現性のある具体的なものを示したいと思い、試しましたが、できませんでした。簡単なマクロでは、きちんとパブリック変数は保...続きを読む

Aベストアンサー

IDは違うけれども、同じ内容の質問のようですね。
http://oshiete.goo.ne.jp/qa/6420530.html

具体的にこんなことをしています、ということをおっしゃれば、話は変わるかとも思います。
今のままでは、いくら説明しても、たぶん納得いかないだろうと思います。

最初に、#3の方のMSのサポートの文章で、
>[VBA] Public 宣言された変数の有効期間
この内容、ご質問者さんは、意味を誤解しているようです。

「ほとんどの場合、プロシージャ終了後も値は保持されますが、
 ……Public 変数がアプリケーション終了時まで有効であること
 を期待する VBA マクロの実装は、推奨されません。」

どうして、保持した変数がなくなってしまうか、いろんな理由はあっても、完成したマクロでは、原因はひとつで、End Sub を通っていないままに終了しているからです。

 「ある Office ドキュメントが VBA のマクロを含む場合、…… Public 変数
  の値が有効である期間は、あるプロシージャの実行を開始
 し、そのプロシージャが "End Sub" で終了するまでの間のみです。」

この文章は間違いです。その話のままだったら、Public 変数など意味がなくなってしまいます。値だって確保しているし、変数は動的です。しかし、実務上、構造化マクロで、きちんと作られたマクロの流れ(ルーチン)が通る間だけだと思ってよいです。

>ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。

Public 変数が、リセットされるというのは、マイクロソフトの文章は間違いに近いです。これは、極論すると、不完全なマクロだということです。しかし、本当に完全なコードを提供出来るかというのは、それは誰も自信などありません。だから、そういう方法を避けるわけです。

Public 変数は、標準モジュールを経由して、ローカルのUserForm に供給を受けるけれども、それを戻すということはしないのです。

図式化するとこうなります。

・ローカルで発生した値 →標準モジュールのPublic 変数 →UserFormのローカルのプロシージャ
・標準モジュールのPublic 変数 → UserFormのローカルのプロシージャ

※ただし、起動時の一回きり、それ以上の持ち回しはしない。逆もしない。

「ユーザーフォームに対してユーザーが任意の引数を渡す方法
 ユーザーフォームから引数を受け取る方法はあるのですか?」
出来ないわけではありませんが、これらは、変数で渡すということはしないということです。

>ただ、ユーザーフォーム aUS 全体で参照し値を変更できる 変数a のようなものを、使えたらいいなあ、と思い、

理屈では、一旦、標準モジュールのPublic 変数に送っておいて、そこから他のプロシージャ等に送ればと思いますでしょうが、それはしないということです。ルーチンが別だからです。

私の基本的な設計の考え方を示しておくと、UserForm自身とか、その中にあるものは、OLEオブジェクトのインスタンスです。つまり、モノ(オブジェクト)がある限りは、値は確保しているのです。だから、UserFormが残っている以上は、変数ではなくて、モノから、値を取得するのです。そのためには、UserForm はModalモードを、Offにしておくのが良いわけです。

例えば、UserForm1.TextBox1.Value とかで取れるわけです。

これは、システム設計の話で、それを見れば分かっていただけます。非表示のワークシートのセルに書くような話は、それは状況(渡す変数の数)によります。ただ、わざわざワークシートのセルに代入する必要はないということです。そのような方法はシステム設計では全体にリスクを高くするので賛成出来ないです。

私の失敗の経験から、Public 変数については、ひとつのルーチン以上に用いないことです。また、動的には用いないことです。一回きりの静的な変数として使うべきです。静的といっても、Static 変数の意味ではなく、文字通り変数を変化させないということです。ただし、時間の間隔やカウントなどの単純なものは別です。

Public 変数が空かどうかチェックする方法も考えられますが、意味がありませんから、それなら、参照渡しにすればよいのです。

IDは違うけれども、同じ内容の質問のようですね。
http://oshiete.goo.ne.jp/qa/6420530.html

具体的にこんなことをしています、ということをおっしゃれば、話は変わるかとも思います。
今のままでは、いくら説明しても、たぶん納得いかないだろうと思います。

最初に、#3の方のMSのサポートの文章で、
>[VBA] Public 宣言された変数の有効期間
この内容、ご質問者さんは、意味を誤解しているようです。

「ほとんどの場合、プロシージャ終了後も値は保持されますが、
 ……Public 変数がアプリケーション終了時...続きを読む

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QExcelのVBA。Staticな変数について

あるプロシージャやfunctionで定義したstaticな変数は、その定義したsubやfunctionで有効です。今回、例えば、static a as integer とSub AAA 内で、定義し、その AAA が呼び出す BBB という ユーザーフォームの中でも staticな変数である a に値を代入したり、変更したりし、その後 sub AAAにまた入ったとき、BBBで変更した内容を保持することができるのでしょうか。

Aベストアンサー

Public 変数側の回答をしてこちら側にも、少し触れておきます。
たぶん、Static 変数と、Public 変数と同じことです。

具体例のない質問なので、お互いがお互いのイメージの中で語られることになって、実体のない応答になるのは仕方がないのですが、まず、スタイルにこだわる前に、エラーのないコードを作ることが第一番ですね。エラーの可能性がみえているのに、それを無視したコードは、いくら格好をつけても、ダメだということです。

>例えばほんの3つとか5つだけ……共通のデータがあった場合、その間で限定的に使える変数などの定義方法があったら便利……。

その共有データの内容にもよりますね。以前も、Function使用する共有変数という質問をみましたが、正直なところ、その回答群は、どれも満足したものがありません。せっかくだから、私は、滅多に使いませんが、三種類用意しておきますが、どれも中級以上のテクニックです。Classも構造体も、エラーが発生すると、変数は飛んでしまいます。実務では、CustomDocumentPropertyのみです。

'CustomDocumentProperty を利用する方法
'標準モジュール
Sub Auto_Open()
 '起動時に設定
 Dim ret As Variant
 Dim dum As Variant
 On Error GoTo ErrHandler
 With ActiveWorkbook
  ret = Application.InputBox("数値を入れてください。", "Input", Type:=1)
  dum = .CustomDocumentProperties("MyData")
  If VarType(ret) = vbBoolean Then Exit Sub
  .CustomDocumentProperties("MyData").Value = ret
 End With
 Exit Sub
ErrHandler:
 With ActiveWorkbook.CustomDocumentProperties
  .Add Name:="MyData", _
  LinkToContent:=False, _
  Type:=msoPropertyTypeNumber, _
  Value:=0 '数値型
 End With
 Resume Next
End Sub
Sub Test1()
 MsgBox TestFunc(5)
End Sub
Function TestFunc(arg As Variant)
Dim var1 As Variant
var1 = ActiveWorkbook.CustomDocumentProperties("MyData")
If arg <> "" Then
 TestFunc = var1 + arg
End If
End Function

'******
'Class のプロパティを使う方法
'*****
'標準モジュール
Public myClass As New Class1 '(実務では、プロシージャ内でオブジェクトを生成してください)
Sub Auto_Open()
  myClass.myVal = 12
End Sub
Sub Test2()
  MsgBox myClass.myVal
End Sub
'----
'Class1
Private propertyVal As Variant
Public Property Get myVal() As Variant
 myVal = propertyVal
End Property
Public Property Let myVal(ByVal NewValue As Variant)
 propertyVal = NewValue
End Property
'******
'構造体を使う方法
'******
Type strctPerson
 Name As String
 Family As String
 AGE As Integer
 Birth As Date
End Type
Dim psn As strctPerson
Sub TestStructure()
psn.AGE = 31
psn.Birth = #2/18/1980#
psn.Family = "Helten"
psn.Name = "London"
End Sub

Sub Test3()
 MsgBox psn.Family & " " & psn.Name & " 年齢:" & psn.AGE
End Sub

Public 変数側の回答をしてこちら側にも、少し触れておきます。
たぶん、Static 変数と、Public 変数と同じことです。

具体例のない質問なので、お互いがお互いのイメージの中で語られることになって、実体のない応答になるのは仕方がないのですが、まず、スタイルにこだわる前に、エラーのないコードを作ることが第一番ですね。エラーの可能性がみえているのに、それを無視したコードは、いくら格好をつけても、ダメだということです。

>例えばほんの3つとか5つだけ……共通のデータがあった場合、その間で限定的...続きを読む

QVBAでfor文の中で、continueしたい

お世話になります。
VBAのfor文の中で、ある条件に合致したら、for の先頭に戻りたいのですが、
方法が分かりません。

VB.net 等の「 Continue For」に当たるものは、VBAに
ないのでしょうか?

何卒宜しくお願いします。

Aベストアンサー

Continue For は昔の VB6 までに物には実装されていませんね VB6 使いの私は知らなかった

for の先頭に戻りたいのではなく、 Next の直前に飛びたいのですよね?
幸いにも VBA には Goto ステートメントがありますので

Sub Sample1()
For i = 1 To 10
If 意除外条件 Then GoTo Next_no_mae

通常の総理

Next_no_mae:

Next i

End Sub

じゃダメですか?
これなら For の直後に飛ぶ事も可能ですが

もしくはこれぐらいしか対処方法はないのでは?
Sub Sample2()

For i = 1 To 10
If 除外条件 Then
Else
通常の総理
End If
Next i

End Sub

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

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

Aベストアンサー

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

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

QVBA モジュールで共通に使う変数の宣言方法

VBAにてプログラミングを覚えている者です。

現在、いくつかのモジュールがあり、それぞれDimにて宣言している共通の変数があります。
いくつものプロシージャに毎回宣言せず、どこかでひとまとめにしたいと思い、色々と調べています。

例えば、

Dim pic1 As Picture
Dim cell1 As String
Dim pass1 As String
Dim pic2 As Picture

などです。


Dimのほかに、Publicの宣言などがありますが、いま一つ使い方がピンときません。

共通宣言する変数をひとつのモジュールとして登録し、活用できると、いざ変更となったときに
その内容だけ置き換えればいいと思うのですが、みなさんはどのように宣言をしていますか?
(例えば、Stringなどは各モジュールで変更するのが大変だと思うのですが・・・)

ヒントを教えていただければと思います。よろしくお願いします。

Aベストアンサー

>モジュールで共通に使う変数の宣言方法

モジュールの先頭に書いたdimで宣言すると,そのモジュールの中だけ(に記入されている各プロシジャ)でパブリックになります。
モジュールの先頭に書いたpublicで宣言すると,全モジュール(に記入されている各プロシジャ)に対してパブリックになります。

「変数宣言モジュール」のようにモジュールを越えて参照させたいという事なので,DimではなくPublicで宣言します。


Module1:
public x as variant


Module2:
sub macro1() ’先に実行する
x = "abc"
end sub


Module3:
sub macro1()
msgbox x
end sub

QVBでグローバル変数を宣言するには

VB初心者ですが。クイズゲームのようなものを作成したいと考えてます。
Private Sub ~ End Sub の中で宣言した変数って他のところに呼び出したり(戻り値として渡す)出来るのでしょうか?
どこでも、いつでも呼び足せるグローバル変数の宣言とはどのようにやるのか、具体的に教えていただけないでしょうか?

Aベストアンサー

>Public a as Integerのように宣言して、初期化するにはどのように記述を行えばよいですか?

>Public a As Boolean = 0
のように記したら”コンパイルエラー”と出ました。

Booleanって整数値取れたかなと思いつつ。
Sub~End Sub内でa = 0を代入したりしてください

扱おうと言うことがあるかどうか疑問だけど

Public Const a As Integer = 10 'グローバルな定数の宣言

QVB上で実行中の無限ループの止め方

今まで、CUIベースのBASICでのプログラムの経験はあるのですが
Visual系のBASICは初心者です。
原因はわかっているのでプログラムの修正はできるのですが
VB上でコンパイルして実行したときに無限ループに陥ってしまって
どうにもプログラムをとめられなくなります。
そんなことがないように、実行前に全てのプロジェクトを保存して
いますので、そんなに実害はないのですが、どうすればとめられるのでしょう・・
今現在は、タスクマネージャーから強制終了させています。

Aベストアンサー

無限ループの一番内側に
DoEvents
を入れておくと、ウィンドウ切替え->デバッガ終了操作が出来ますよ

危なそうなとこにも入れておくと、何かと安心です。

QEXCEL(VBA) セルをクリックしたときの処理

何度もお世話になります。

A5:A20のどれかをクリックしたときに
クリックしたセルが値が入力済みか確認してから
ファイルを名前を付けて保存したいのですが
クリックしたという情報(イベント?)の取得方法が
わかりません。

(1)どのようにチェックすればよいのでしょうか?
(2)また、皆さんはどのようにしてこのような問題を解決してるのでしょうか?

よろしくお願いします。

Aベストアンサー

Sheet1だとして、
Sheet1のマクロで

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'
If Target.Column = 1 And Target.Row >= 5 And Target.Row <= 20 Then
If Target.Value <> "" Then MsgBox "入力済み"
End If
'
End Sub

と入れると、クリックしたセルがA5からA20のどれかで
かつセルに値が入っているときのみ”入力済み”とメッセージが表示されます。
このメッセージ表示の部分を、「名前を付けて保存」の処理に置き換えてはいかがでしょうか。

Q別のシートから値を取得するとき

Worksheets("シート名").Activate
上記のを行ってから別シートの値を取得するのですが、
この処理を行うと指定したシートへ強制的にとんでしまいます。。。

※イメージ
For ~ To ~
  Worksheets("シートA").Activate
  シートAの値取得
       :
  Worksheets("シートB").Activate
  シートBの値取得
Next

このイメージ処理を行うとものすごい勢いで画面がチカチカします。。。
シートを変えずに他のシートから値を取得する方法はないのでしょうか。
教えてください!

Aベストアンサー

Worksheets("シートA").Range("A1")

みたいな感じでできませんか?


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報