FC2ブログ

Excelじゆうちょう

Excelのお絵描きツール『りっぷ2(りっぷつぅ)』のサポートページ、まずは「はじめに」をご覧ください。 [NewEntry] [Admin]

記事更新カレンダー

11 « 2018-12 « 01
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -

やたらに多いカテゴリ

比較的新しい記事

新しいコメント

ありがたいブログ拍手

拍手コメント一覧(拍手はしない)

さみしいトラックバック

申し訳ないプロフィール

申し訳ない

管理人  [ 申し訳ない ]

pxivもやってます
リンクの一番上からのぞきに来てください
※閲覧にはユーザー登録が必要です

RSSってなんぞ?

広告は消せないらしい

FC2Ad

        --------       スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

        2010-06-17       標準モジュールで定数

標準モジュールだけの機能をもうひとつ。
これはおすすめ、大変便利です。

Publicな定数を定義できます。

定数とは、値を変更できない変数のことで、例えば以下のように定義します。


'【コードウインドウの宣言部】
Private Const PI As Single = 3.141593 '円周率


宣言部とは、コードウインドウの先頭から最初のプロシージャまでの領域です。
プロシージャの中に定数は定義できません。
また、ExcelVBAには最初から用意されている定数も数多くあります。

定数名  |値(16進数)|色
━━━━━┿━━━━━┿━━━━
vbBlack  |    0 |黒
vbWhite  | FFFFFF |
vbRed   |   FF |
vbGreen  |  FF00 |
vbBlu   | FF0000 |
vbMagenta | FF00FF |マゼンタ
vbYellow |  FFFF |
vbCyan  | FFFF00 |シアン

これは色の定数です。
色のRGB値だけではいまいちパッとしませんが、定数名ならなんとなくイメージがわきますね。
こういった定数は、こんなふうに使います。

【注意】
Excel2003以前のバージョンではセルの塗りつぶしをRGBで指定すると誤差が生じる可能性がありますので、Excel2007で実行してます。


'【コードウインドウ】
Private Const PI As Single = 3.141593 '円周率

Private Sub testConst()
Cells(1).Interior.Color = vbCyan 'セルの色をシアンにする
Cells(1) = "半径3の円の円周は " & 3 * 2 * PI '面積 = 直径 * 円周率
End Sub


↓使い方は普通の変数と同じ↓
Private定数

で、上の「PI」のように自分で用意した定数なんですが、基本的にPrivate指定で宣言しなければなりません。
もし複数のシートで同じ定数を使いたい場合は、それぞれのモジュールに記述する必要があります。
ただし、標準モジュールに限ってはPublic指定が可能なのです。
特定のモジュールでしか使わないものなら問題ありませんが、複数のモジュールを組み合わせて作品を作る場合、共有して参照したい定数もあるかもしれません。

Excel2007ではセルの色をRGBフルカラーで設定できるため、先ほどの色の定数以外に独自の色定数を用意しておけば便利です。
やってみましょう。


'【標準モジュールのコードウインドウ】
Public Const GRAY_25 As Long = &HC0C0C0 '25%黒
Public Const ORANGE As Long = &H80FF& 'オレンジ
Public Const LIKE_BURUE As Long = &H60C0A0 '緑っぽい混色

'【Sheetモジュールのコードウインドウ】
Private Sub testPublicConst()
Cells(1, 1).Interior.Color = GRAY_25
Cells(2, 1).Interior.Color = ORANGE
Cells(3, 1).Interior.Color = LIKE_BURUE
End Sub


↓どのモジュールからでも定数を参照できる↓
Public定数

【注意!】
16進数で4桁以下の値の場合、符号付きとして扱われます。
RGB値では負の値を想定してませんので、オレンジの値のおしりに"&"を加えています。
もし「Public Const ORANGE As Long = &H80FF」だとすると、FF80FFとおかしな値が設定されてしまいます。

↓青成分がFFになって、薄いマゼンタに!↓
16進数の補数誤差
スポンサーサイト

        2010-06-10       標準モジュールでイベント(もどき)

標準モジュールでなんと、イベントが扱えるんです。
(厳密に言うとイベントじゃないんですが、それは後述)

使えるのはこのふたつ、Auto_OpenプロシージャとAuto_Closeプロシージャです。
前者はブックを開いた直後に、後者はブックを閉じる直前に実行されます。
そうです、WorkbookモジュールのWorkbook_OpenイベントとWorkbook_BeforeCloseイベントとほぼ同じ動きをします。
「ほぼ」というのは、若干の違いがあるからです。

第一に、標準モジュールの方はマクロで開いたり閉じたりした時に実行されません。
例えば、このようなマクロがあるとします。


'【標準モジュールのコードウインドウ】
Private Sub Auto_Open()
MsgBox "Auto_Open"
End Sub
Private Sub Auto_Close()
MsgBox "Auto_Close"
End Sub

'【Workbookモジュールのコードウインドウ】
Private Sub Workbook_Open()
MsgBox "Workbook_Open"
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox "Workbook_BeforeClose"
End Sub


↓普通に開いて閉じたらこの順番で実行↓
Workbook_Open
Auto_Open
Workbook_BeforeClose
Auto_Close

Workbookモジュールは標準モジュールより先に起動します。

↓マクロで開いて閉じたらこの順番で実行↓
Workbook_Open
Workbook_BeforeClose

標準モジュールの方は反応しません。

第二に、Auto_OpenプロシージャとAuto_Closeプロシージャはアクセス修飾子に「Public」を指定できます。
イベントではこんなこと許されません。

第三に、決定的なのがAuto_OpenプロシージャとAuto_Closeプロシージャはイベントの発生を抑止しても動きます。
Application.EnableEvents = Falseを実行すると、アプリケーション(つまりExcel)自体のイベントの発生を抑止することができます。
当然、Workbook_OpenイベントとWorkbook_BeforeCloseイベントは発生しません。
そんな中でも、標準モジュールのそれはしっかり起動してくれます。

        2010-05-19       標準モジュールより、関数を…2

標準モジュールに記述したFunctionプロシージャは、ワークシート関数と同じように使うことができました。
今回は、それを少し補足します。

■アクセス修飾子は影響しません
PublicでもPrivateでも、関係なく参照できます。


'【標準モジュールのコードウインドウ】
Private Function getBookName() As String '「Public」でも結果は同じ
getBookName = ActiveWorkbook.Name 'ブック名を取得
End Function


↓Private指定でも使えます↓
Privateでも使用可能

そうすると、ひとつ問題が発生します。
Privateでスコープを限定すれば、別のモジュールで同じ名前のプロシージャを作ることが可能です。
ですので、別々標準モジュール「Module1」と「Module2」それぞれに、同じ名前でPrivateの関数を定義してしまうと怒られてしまいます。


'【標準モジュール「Module1」のコードウインドウ】
Private Function getBookName() As String '同じ名前
getBookName = ActiveWorkbook.Name 'ブック名を取得
End Function

'【標準モジュール「Module2」のコードウインドウ】
Private Function getBookName() As String '同じ名前
getBookName = ActiveWorkbook.Path '絶対パスを取得
End Function


↓どっちの標準モジュールの「getBookName()」か判らない↓
名前が適切ではありません

そんな時は、明示的にモジュール名を指定します。

↓上のマクロを、両方の標準モジュールに記述してます↓
標準モジュール名を指定

あれれ?
関数名の大文字小文字が補完されてないぞ、気が効かないなぁ。

■引数にRangeオブジェクトを使用できます
他のワークシート関数と同じように、引数にセル範囲を入力します。
当然ながら、シートやオートシェイプなど、ワークシート関数で指定できないオブジェクトは使えません。
もちろん、戻り値はセルに入力できる値でないといけません。

■Excelの操作には制限があります
VBAからFunctionプロシージャを呼び出す場合と違って、ワークシートから呼び出した場合は多くの操作ができなくなります。
何がOKで何がNGなのか、基準がよくわからなかったので試してみた項目だけ列挙します。
テストはExcel2003で行いました、他のバージョンでは分かりません。
もしかしたら、命令の仕方でも変わってくるかもしれません。

【操作可能】
ツールバーの表示、非表示
オートシェイプの選択
オートシェイプの移動
オートシェイプのサイズを変更
オートシェイプの塗りつぶしを変更
ワードアートの選択
ワードアートの移動
ワードアートのサイズを変更
デザインモードでのコントロールツールボックスのコマンドボタンの選択
デザインモードでのコントロールツールボックスのコマンドボタンの移動
デザインモードでのコントロールツールボックスのコマンドボタンのサイズを変更
グラフの選択
グラフの移動

【命令無視(次の行へ進む)】
セルの選択変更
セルの塗りつぶし
セルのフォントの色を変更
アクティブシートを変更
アクティブウインドウの最大化、最小化
アプリケーションの最大化、最小化
ウインドウ枠の固定
ウインドウの分割

【マクロ停止(以降の行は実行されない)】
セルに入力(戻り値でなく、コードでの命令)
フォームコのマンドボタンを選択

【Excelが強制終了】
グラフの元のデータを変更

↓きゃあぁあ!!↓
Excelが強制終了

Functionプロシージャをワークシート関数として使用する場合は、余計なことはしない方がよさそうです。

        2010-05-11       標準モジュールより、関数を…1

マクロはモジュールに記述します。

中でも、Functionプロシージャは戻り値を設定することができる、いわゆる関数です。
関数といえば、Excelにはワークシート関数というものがあります。
マクロとは違って自由に作り込むことはできませんが、色々な統計や検索等ができて大変便利です。

いいえ、実はできるんです。
Functionプロシージャをワークシート関数として使うことができるんです。
今回は、その方法を紹介します。

それでは、試しにシート名を取得する関数を自作してみましょう。

まずは、VBEで標準モジュールを用意します。
ワークシートモジュールではいけません、クラスモジュールでもだめです、必ず標準モジュールです。
マクロはこんな感じです。


'【コードウインドウ】
Private Function getSheetName(Optional Sheet_no As Long) As String
If IsMissing(Sheet_no) Then '引数が省略されていれば
  getSheetName = ActiveSheet.Name 'アクティブシート名
ElseIf 0 < Sheet_no And Sheet_no <= Sheets.Count Then '引数のシート番号があれば
  getSheetName = Sheets(Sheet_no).Name 'シート名
Else '引数のシート番号がなければ
  getSheetName = "なし!" 'そんなシートないよ
End If
End Function


後は、シートでいつもの通り関数を呼び出します。
ちなみに、このFunctionプロシージャは引数をひとつ取ってその値と同じシート番号のシート名を返します。
もし、引数のシート番号がなければ"なし!"と返してくれます。
また、引数を省略するとアクティブシートのシート名を返してくれます。

↓左が入力した数式表示、右が計算結果表示↓
シートでFunction(×)

ちょっと変ですね、引数を省略したのにアクティブシート名が返ってきてません。
原因は、引数の変数の型にありました。
上の2行目の
If IsMissing(Sheet_no) Then
で、引数が省略されたかどうかを判定しています。
ですが、この場合は引数の型をVariantにしておく必要があります。
上のコードでは1行目が、
Private Function getSheetName(Optional Sheet_no As Long) As String
でしたので判定できませんでした。

そうそう、Optionalは引数を省略可能にするというキーワードです。


'【コードウインドウ】
Private Function getSheetName(Optional Sheet_no As Variant) As String
If IsMissing(Sheet_no) Then '引数が省略されていれば
  getSheetName = ActiveSheet.Name 'アクティブシート名
ElseIf 0 < Sheet_no And Sheet_no <= Sheets.Count Then '引数のシート番号があれば
  getSheetName = Sheets(Sheet_no).Name 'シート名
Else '引数のシート番号がなければ
  getSheetName = "なし!" 'そんなシートないよ
End If
End Function


変数の型を修正しました、バッチリですね。

↓Sheet1、Sheet2の2シート構成のブック↓
シートでFunction(○)

この関数は標準モジュールのFunctionプロシージャを利用したものです。
マクロを有効にしていないと使えません。

↓マクロを無効↓
シートでFunction(マクロ無効)

 | HOME | 

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。