LastUpdate: 2024/08/10 20:26:40
Home 戻る
001 タイムスタンプが更新していないのに変わる
002 標準のフォントなどの設定の仕方
003 シートと、印刷プレビューでセルの高さが異なり、行が欠ける!
004 起動時の書式設定
005 マクロを[Ctrl]+[Shift]+[v]に割り付けたが動作しない!
006 別の場所のセルを張り込む方法
007 右寄したいんだけど、スキマをあけたい時の書式設定
008 完了日付を設定したら、その行全体の色を変えたい時など
009 曜日の表示方法
20050414 ユーザー書式
20050905 シート数の制限
20051122 文字列の連結
20060427 列の表示、非表示
20060503 セルの文字量に連動して、縦幅が変わらないんだけど
20060603 ブック間のシートのコピーについて
20070216 ワークシートを非表示にする方法
20071215 名前を付けて保存 が異様に遅い
20080509 ほかのユーザーによって変更された可能性があります
20080513 ファイルパスをセルに入力すると、ハイパーリンクになってしまう
20080523 ファイル保存の時、既存のファイルを上書きしたい
20080528 入力規則に注意
20081010 行数 列数
20090123 #N/A 条件付書式
20090226_指数表示になったデータを文字として表示させたい
20090512_表示書式
20090627_シートを並べて表示したい
20110106_商と余を求める
20190605_日付や時刻のマイナスを表現する
20190705 数字の上に、数値バーを重ねて表示
20200404 セルコピーした後の数字の上に、ミニメニューを消したい
20220611 セル範囲どうしの比較を見やすく
20240711 シートをコピーすると「名前'○○'は既に存在します。」の対処
20240711 別インスタンスでExcelを起動する
20240716 長いSQLを文字列変数で機銃Tしたいときの作業用シート
VBA001 エクセルのマクロでDAOのクリエイトで失敗するとき
VBA002 エクセルのマクロでコピーメソッドを使用するときの注意点
VBA003 "中断モードでは入力できません。"のマクロアラートが表示されてしまう。
VBA004 マクロが含まれていないのに、"マクロが含まれています。"のメッセージが表示されてしまう。
VBA005 VBAの処理速度。
VBA006 エクセルのVBAで、ワークシート関数を使用する方法。
VBA007 図形のテキストボックスのテキスト文字をVBAで編集する方法。
VBA008 プリンターの制御
VBA009 ファイルオープン時の制限
VBA010 Run関数でのExcelとの違い。
VBA011 シートの複数セレクトについて
VBA012 値の貼り付けのマクロ
VBA013 マクロ実行中に画面の再描画を停止
20080512 非表示でブックを開く
20080513 2003と2007で保存するファイル形式を変更してみる
20080523 Excel データをSQL抽出
20080602 複数カラムが一致する行の抽出方法
20080612 オラクルからデータを取得
20080612 シートの初期化
20080612 テキストボックス図形 の文字列を取得したい
20090121 全てのセルをシート間でコピー
20240711 シートをコピーすると 名前'○○'は既に存在します。が表示される
20090212_16進数で計算
20090303_オブジェクト型変数の初期値判定
20090424_フォルダを丸ごと削除
20090521_VLOOKUP_で_#N/A_になったとき、ブランク表示したい
20090702_VBAでオブジェクト指向コーディング
20090713_セルの選択いろいろ
20090713_セルの名前参照
20240607_動的にボタンを配置
20240607_スクロールパネル風
20240707_動的に複数ボタン
20240710 以下同文で空白にされたセルに値を埋め戻す
20240718_CallBackを実装する
20240728 Bind変数を使ったSQL
20240810 例外処理のサンプルSQL
エクセルファイルを開いている間、タイムスタンプはCPU日付に変わる。更新せずに閉じると前のタイムスタンプに戻るようである。
エクセルファイルを開いている間に、タスクマネージャーよりエクセルのプロセスを強制終了させると日付は戻らないままになってしまうので注意。考慮方法は、エクセルファイルの属性を、Readonlyにしておくことである。
1999/05/31 N
書式→スタイル で 標準スタイルを変更すれば良い。
セルの行数が変わると、セルの高さも自動的に変わる。この高さは標準のフォントを元に計算している。しかしプリンタドライバの兼ね合いもあり完全に高さを調整する事はできない。
Office97 98/03/05 マイクロソフトサポートセンタ
XLSTARTフォルダに、book.xlt、sheet.xltを置けばよい。ただし、マニュアルには、Documents and Settings 配下に置くようにと書かれているが、C:\Program Files\Microsoft Office\Office\XLStart が優先される事もあった。
しかし、Office2003 では、C:\Documents and Settings\UserName\Application Data\Microsoft\Excel\XLSTART の方が優先されたようにも思われる。
PERSONAL.XLS の日付を見て、どちらが有効になっているかを確認するのも有益かと思われる。
Excel オンラインヘルプ
「ブックとシートの設定を元に戻す」にて検索
2004/11/19
Office2016/Office365 の場合
Excel上で新規ブック作成時に参照されるテンプレートは
C:\Users\ユーザー名Documents\Office のカスタム
テンプレート\Book.xltx
Excelを起動した際に参照されるテンプレートは
C:\Users\ユーザー名\AppData\Roaming\Microsoft\Excel\XLSTART\Book.xltx
[コンテキストメニュー]→[新規作成]→[Microsoft Excel ワークシート]で参照されるブックファイルは
C:\Program
Files\Microsoft Office\root\vfs\Windows\SHELLNEW\EXCEL12.XLSX
http://officetanaka.net/excel/function/tips/tips83.htm
https://dev.classmethod.jp/tool/office/change_new_excel_file/
自分でよく「値だけ貼り付け」のマクロを作り、[Ctrl]+[Shift]+[v]を登録したにもかかわらず動作してくれないことが多い。
以下の点に注意して再設定を試みよ。
大文字モードになっているときに、[Ctrl]+[Shift]+[v] を押下すると、
小文字の“v”になり、マクロが認識してくれません。ご注意!
2002/07/11
2002/07/26
2002/11/19
=NOT(ISBLANK($A1))
上記のように指定すると、その行のE列に何かを入れたら、背景がブルーになります。
ひとつのセルで設定して、あとは書式のコピーをすると、楽です。
2003/05/09
=TEXT(B2,"AAA")
2003/09/17
ヘルプで調べる時のキーワード
表示形式で使われる書式記号
ZZ9のような事をしたい時は
??0 でOK
Excel 2003 使用可能メモリに依存 (既定では 3) HELP:「Excelの仕様および制限」参照
& で行います a1 & a2 とか
結合されているセルに対しては、この機能は無効のようです。
コピーの方法は、2種類ある。
メニューバーから行う方法
シートを選択して [編集]→[シートの移動またはコピー]
マウスで行う方法
シートのタブ上で左ボタンを押し続け、アイコンが変わったら、そのまま、コピー先のシートへドラッグする。
注意点
複写元のシートに、シート間の連携が有る場合、複写先のシートでも連携を維持しようとするので注意が必要である。
シート「データ」には、表紙のデータからの連携が設定されています
「データ」シートをコピーすると…
元.xls の 表紙シート のB1 と連携するようになります。この状態の場合、先.xls を開く時に、元.xlsが存在しないと、リンクエラーになってしまいます。
リンクを解消するには、「リンクの編集」を選択し、表示されるダイアログボックスから「リンクの解消」を選択すれば良いです。
Excel2003
無効な実際にアクセスできないドライブが残っていると遅いらしい。
[ファイルエクスプローラ]→[ネットワークドライブの切断] から 削除すると改善する。
XLSファイルを開いて保存しようとした場合、以下のメッセージが表示されてしまった
自分以外のユーザーが変更してはいない。
ネットワークの先のファイルを更新しようとした場合、ネットの遅延により、発生する事があるそうだ
http://support.microsoft.com/kb/324491/ja
他のユーザーが変更していないならば、「変更を上書きする」で、OK
ハイパーリンクにする/しない は、以下で設定される。
エクセルの入力規則を使うと、「このセルにはこのような値しか入っていなければだめだ」というチェックをかける事ができるはずのものであるが…。
例外がある。
必ず入力されている事をチェックする場合、いくら入力規則でガードをしても、セルを入力状態にしていいない状態で、「DEL」キーなどを押すと、入力チェックが効かない。
例:1または2が入力されている事を期待する設定
[バックスペース]→[エンター]だと、チェックされるが
[Delete]で消去できてしまう。
DELETEキーの場合は、入力されていないからだ…と思われる。
入力規則は、あくまで入力モードにおける、規則のようだ
その証拠に、値の貼り付けをおこうと、他も文字も入ってしまう
Excel2003 以前 | 6万5536行 | 256列 |
Excel2007 以降 | 100万行 | 1万6384列 |
以下のように設定すれば、 #N/Aの時の属性を設定できる
ERROR.TYPE
エラー値 | ERROR.TYPE 関数の戻り値 |
#NULL! | 1 |
#DIV/0! | 2 |
#VALUE! | 3 |
#REF! | 4 |
#NAME? | 5 |
#NUM! | 6 |
#N/A | 7 |
その他 | #N/A |
ココにヒントあり
http://blogs.yahoo.co.jp/bardiel_of_may/26310406.html
表示形式は 三つまでの数値の書式と、文字列用に四つ目の書式を持つことができます。
各書式は次のようにセミコロン( ; )で区切って指定します。
<正数>;<負数>;<ゼロ>;<文字列>
二つのセクションだけを指定した場合、最初のセクションは正数とゼロの表示形式になり、二番目のセクションは負数の表示形式になります。
<正数及びゼロ>;<負数>
一つのセクションだけを指定した場合は、その表示形式がすべての数値に適用されます。
ひとつのブック内のSheet1とSheet2を、並べて同時に見たいときは、以下のようにすれば良い
新しいブックが表示されました。二つは同じブックを指している。変更内容は、もう一方にもリアルタイムで変更されます。
それぞれのブックの表示するシートを自由に選択すれば良い。
配置設定にて「折り返して全体を表示する」をチェックする事がポイント
余りを求めるときは、 MOD関数
商を求めるときは、 TRUNC (切捨て)を用いる
TRUNC は 小数部を単純に除く関数である。
似たような関数で、INTは 小さい方向に丸めるものである。
TRUNC(-3.3) = -3
INT(-3.3) = -4
1、2などの数字が文字として入力されているものを、数値に直す方法について
*1を行った結果は数値になる事を利用する
区切り文字ウィザードを用いる方法
対象を選択し、[データ]→[区切り位置]を選択
Excelの日付の基準を1904年スタートにすると、マイナスが表現できる。
基準の切り替え方法
すでに日付が設定されている状態で、基準を変更すると、表示日付が4年と1日ずれるので、注意。
また、基準日が異なっているブック間で日付データをコピーすると、同様にずれるので、注意
[条件付き書式]→[データバー]で設定できる
コピーした後に表示されるミニメニューを表示させないようにしたい。
エリア2の四つのセルを選択状態にする
比較する対象のセルどうしを選択する。ことのとき、絶対参照ではなく、相対参照にしておくのがポイント
マクロで対応するのがてっとり早い
このダイアログで「はい」を選べば、別インスタンスでExcelが起動される。
別インスタンスのExcel間は、マクロの干渉もないし、書式を保った複写もできないので、注意
文字列連結1
SQLを記載する | strSQL | ||
SELECT | strSQL = "SELECT " _ | = SUBSTITUTE( SUBSTITUTE("@1 = ""@2 "" _","@1",$C$1), "@2",B3) | |
KEY1 | & " KEY1 " _ | = SUBSTITUTE( " & "" @1 "" _","@1",B4) | |
,KEY2 | & " ,KEY2 " _ | = SUBSTITUTE( " & "" @1 "" _","@1",B5) | |
FROM | & " FROM " _ | ||
TEST_TABLE; | & " TEST_TABLE; " _ | ||
& " " _ |
文字列連結2
SQLを記載する | strSQL | ||
SELECT | strSQL = "SELECT " | = SUBSTITUTE( SUBSTITUTE("@1 = ""@2 ""","@1",$C$1), "@2",B3) | |
KEY1 | strSQL = strSQL & " KEY1 " | = SUBSTITUTE( SUBSTITUTE("@1 = @1 & ""@2 ""","@1",$C$1), "@2",B4) | |
,KEY2 | strSQL = strSQL & " ,KEY2 " | = SUBSTITUTE( SUBSTITUTE("@1 = @1 & ""@2 ""","@1",$C$1), "@2",B5) | |
FROM | strSQL = strSQL & "FROM " | ||
TEST_TABLE; | strSQL = strSQL & " TEST_TABLE; " | ||
strSQL = strSQL & " " |
エクセルをインストールするときに、データアクセスオブジェクトをインストールしておかないとダメである。
1999/05/31 N
複数のマクロを同時に動かすときや、ほかの処理と同時に動く恐れのあるときは、使用しない方が良い。
クリップボードを使用するようなメソッドを使用すると、タイミングによって予期しない内容がクリップボードに設定されている事が、充分に考えられる。
1999/06/22 N
レジストリが壊れているときに表示されることがある。
OFFICE全体をアンイントールして、オフクリーン(バリューパックにある。)を実行後、OFFICE全体を再インストールしてみる。
(マイクロフトサポートセンタ より 98/05/22)
マイクロソフトからは、特に情報は公開されていない。他のHPでも同じ障害が報告されていた。最終的に、大橋が、セルにつけていた名前を削除することによりこの現象がでなくなることを発見する。
1999/06/10 N
ワークシート上に関数が一つでも記述されていると、遅くなる。不用意な関数記述は避けること。
以下にコーディング例を示す。(切り捨て関数を使用した例)
Public Sub main()
Dim wk_d As Double
wk_d = 1.015
wk_d = Application.WorksheetFunction.RoundDown(wk_d * 1000, 0)
MsgBox wk_d
End Sub
Shapes("txt_name1").TextFrame.Characters.Text = "あいうえおかきくけこさしすせそああああああ ああああああいいいいいいいいいい"
"txt_name1"は、左上の名前で指定した項目名。
VBAで印刷するとき、Apllication.Printerにセットする名前は、ネットワークパス名等の長い名前が必要となる。VBで取得できる名前では不適である。名前の取得方法は、win.iniの[device]のキーをVBのprinter.deviceNameで取得することが可能である。(見本はxPrnLongNameGet「中部住宅」
だったかな?)
なお、Wordは短い名前でもセット可能である。不思議
97/08/08
VBAでファイルをオープンするとき、ファイル名はフルパスを使用すること。相対パスではうまく行かない。なお、Wordでは相対パスでもOKである。不思議 97/08/08
ExcelのRun関数は、引数を伴うことができるが、Wordはできない。
引数を渡す必要があるときは、WORDのドキュメント上にダミーのテキストボックスを張り付けて文字情報を貼り付ける。その後関数をRun関数で起動してその関数内でテキストボックスの文字列を取得する。
VBの例
'*** ワードにインターフェイス情報を送る
owrdappPrint.ActiveDocument.TextBox1.Text = Command
'*** マクロの起動
dummy = owrdappPrint.Run("main")
WORD VBAの例
MsgBox ThisDocument.TextBox1
条件により、任意のシートを選択したい時、Array関数を使うと一度に固定的に指定しなくてはならない。下記の方法を使用すると、複数選択した後でさらに追加選択することができる。 97/10/02
例)シート"aaaa", "bbbb"を選択した後、セルに値を代入し、その後でシート"cccc"を追加選択する。
Sheets(Array("aaaa", "bbbb")).Select
Sheets("aaaa").Activate
Range("A1").Select
ActiveCell.FormulaR1C1 = "a"
Range("A2").Select
ActiveCell.FormulaR1C1 = "c"
Range("A3").Select
Sheets("CCCC").Select (Replace)
Sub 値の貼り付け()
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End Sub
2002/08/28
少し早くなる。モドし忘れに注意
Application.ScreenUpdating = False
2004/04/16
GetObject を用いれば、水面下でブックを開いて処理ができる。
Dim wb As Workbook Application.ScreenUpdating = False Set wb = GetObject("c:\ddd\eee\book1.xls") Application.ScreenUpdating = True 'wbに対してデータ取得処理 ' wb.Close False Set wb = Nothing
2003で、2007形式で出力してみたら、FileFormat は 51が採用されていた。
'バージョンによって、エクセルの保存のファイルフォーマットを変更する Dim lngFileFormat As Long If xBasExcelApplicationHelper.IsVersionGreater2007 Then lngFileFormat = 51 Else lngFileFormat = -4143 End If 'ファイルをセーブする On Error GoTo ERR_HANDER currentBook.SaveAs Filename:=outputFileName, _ FileFormat:=lngFileFormat, Password:="", WriteResPassword:="", _ ReadOnlyRecommended:=False, CreateBackup:=False
'エクセルのアプリケーションが2007以上かを判定する '2007以上の場合は、trueを返却する Public Function IsVersionGreater2007() As Boolean Dim excelVersion As Double Dim new2007Version As Double new2007Version = 12 excelVersion = CDbl(Application.Version) If excelVersion >= new2007Version Then IsVersionGreater2007 = True Else IsVersionGreater2007 = False End If End Function
Excelのバージョンは、2003は"11.0" 2007は"12.0" であった
VBAマクロで、ファイルを保存する際、同名のファイルが既に存在すると、上書き確認メッセージが表示されてしまう。
メッセージを表示せず、自動で保存したい場合は、どうするか?
方法は二つある。
方法1は、アラートメッセージが一切出力されなくなる。他の予期しないメッセージも、表示されなくなってしまうので、できれば採用したくない。
方法2は、簡単な仕様であるが、既存ファイルの存在チェック及び、削除の実装が必要となる
Public Function IsFileExists(pathName As String) As Boolean Dim objFOS As FileSystemObject Set objFOS = New FileSystemObject IsFileExists = objFOS.FileExists(pathName) End FunctionPublic Function FileDeleteForce(pathName As String) As Boolean Dim objFOS As FileSystemObject Set objFOS = New FileSystemObject objFOS.DeleteFile pathName, True '強制削除 End Function
上記はいずれも、microsoft scripting runtime を、参照設定で、有効にする必要がある
詳しい説明はココ
http://support.microsoft.com/kb/316934/
参照設定が必要である
Dim cn As New ADODB.Connection Dim rs As ADODB.Recordset Dim sss As String cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Properties("Extended Properties").Value = "Excel 8.0" cn.Open ThisWorkbook.FullName Set rs = New ADODB.Recordset Call rs.Open("select * from [ko1$]", cn, adOpenStatic) sss = rs.Fields(1).Value 'これをすると、レコードセットの内容を、一度に、セルに貼り付けてくれる Worksheets("sheet1").Cells(1, 1).CopyFromRecordset rs20080605 補足
CopyFromRecordset 少し、注意がいる。
項目長が長いと、例外が発生してしまう 991文字を超えるとダメ?
http://www.accessclub.jp/bbs6/0006/das1544.html
以下のようにすれば、貼り付けはできるが、このソースは、CopyFromRecordsetに比べると、かなり遅い
' Dim iRow As Long ' ' Dim iColCount As Long ' iColCount = recordset.Fields.count ' ' With recordset ' ' iRow = 2 ' ' Do Until .EOF ' For iCol = 1 To iColCount ' wSheet.Cells(iRow, iCol) = .Fields(iCol - 1).Value ' Next iCol ' ' .MoveNext ' ' iRow = iRow + 1 ' ' Loop ' End With
よく失敗する件
- 項目名は、数字始まりは使えない。
- 数字と文字が混じっていると、型の判別が正しく行われず、「型が合っていない」のメッセージが表示されてしまう事もある→英字をまぜた文字列するなどの考慮をした方が安定する。
ワークシート関数などでは、Find関数などがあるが、これは、一つのセルを検索条件として指定する方法でしかない。
A='1' and B='2' などと行いたい場合は、オートフィルターを用いるか、ADODBなどのSQL機能を用いるしか、方法が無い。
オラクルから、手軽に データを取得したい時の方法
取得する方法は、いろんな方法がある。oo4oはオラクル固有な機能が使え、レスポンスも良く、ベストなのだが、oo4oモジュールをクライアントにインストールしなければならないのがデメリットとなる。
ベターなのは、ADO-OLEDBと思われる。前提条件は、最低限のオラクルクライアント(インスタントクライアントがあれば良い)がインストールされている事でだけである。
Private Sub CommandButton1_Click() '以下を参照して作った 'http://www.atmarkit.co.jp/fdb/rensai/excel2oracle02/excel2oracle02_2.html Dim oraconn As New ADODB.Connection ' データベースに接続する Dim connectionString As String 'ADO+ODBC の場合 connectionString = "DSN=localhostのodbcデータソース;UID=SHODAI;PWD=SHODAI" 'ADO+OLE DB接続の場合 connectionString = "Provider=OraOLEDB.Oracle;Data Source=localhost:1521/ora;User ID=SHODAI;Password=SHODAI;" oraconn.connectionString = connectionString oraconn.Open Dim recordset As ADODB.recordset Set recordset = oraconn.Execute("select sysdate from dual") Call PasteHeaderAndDataFromRecordset(Sheet2, recordset) End Sub Private Function PasteHeaderAndDataFromRecordset(wSheet As Worksheet, recordset As ADODB.recordset) '項目ヘッダの貼り付け Dim wField As Field Dim iCol As Long Dim wkStr As String For Each wField In recordset.Fields '項目名に $ があった場合は、削除する wkStr = wField.Name wkStr = Replace(wkStr, "$", "") iCol = iCol + 1 wSheet.Cells(1, iCol) = wkStr Next wField 'データの貼り付け wSheet.Cells(2, 1).CopyFromRecordset recordset 'データ項目が長いとエラーになるらしい 'http://www.accessclub.jp/bbs6/0006/das1544.html '手動で貼り付けるように修正する 'これ、遅い ' Dim iRow As Long ' ' Dim iColCount As Long ' iColCount = recordset.Fields.count ' ' With recordset ' ' iRow = 2 ' ' Do Until .EOF ' For iCol = 1 To iColCount ' wSheet.Cells(iRow, iCol) = .Fields(iCol - 1).Value ' Next iCol ' ' .MoveNext ' ' iRow = iRow + 1 ' ' Loop ' End With End Function
workSheet.Cells.Clear
cells は、すべてのセルを返却する。 Clear系のメソッドは、ClearContent など いろいろあるが、Clearはすべて削除してくれる。
ただし図形オブジェクトは削除してくれない。また、セルのタテ ヨコ の幅 までは、戻してくれない
以下のようにすれば、図形も含めて、キレイになるかも!
Dim wkShape As Shape For Each wkShape In arg.Shapes wkShape.Delete Next wkShape arg.Cells.Clear arg.Cells.Delete
エクセルのシート上で、テキスト図形を用いて、複数改行可能な情報を管理しているとする。
この文字列の取得方法は?
この図形は、Shape オブジェクトである。Shapeオブジェクトは、コレクションであるShapesに格納されている。
コレクションから取り出す時の名前がわからない。excel2007では、わかったような気もするが、2003ではどうするの?
結局、自分で For Eachで回して、調べた
名前がわかったところで、テキストの取得は、以下のようになるようだ
注意
シェイプの文字列、あまり長いテキストは、終わりが切れてしまう。240文字くらいまでしか、取得できない?
通常のテキストボックスでマルチライン=trueで使用した方が、よさそうだ
シート2の全てのセルを シート3にコピー
Call Sheet2.Cells().Copy(Sheet3.Cells)
エクセルシート上、16進数は文字列で表現する。
例として、16進数に一定の値を加算したいような時のマクロ関数を作ってみた
Public Function IncrementHexValue(inHexValue As String, Increment As Long, FormatSize As Long) As String Dim strReturn As String '入力値を10進にする Dim lngValue As Long lngValue = Val("&h" & inHexValue) 'インクリメント値を加算する lngValue = lngValue + Increment '16進の文字列に変換する strReturn = Hex(lngValue) '出力の桁数を整える Dim wk As String Dim ix As Long For ix = 1 To FormatSize wk = wk & "0" Next ix strReturn = wk & strReturn strReturn = Right$(strReturn, FormatSize) IncrementHexValue = strReturn End Function
IncrementHexValue("00FF",1,4) の戻り値は "0100" となる
今一度、シンプルに 16進 10進変換
'10進数を16進数に変換 ' Dec:10進数 ' MinimumSize:16進の最低桁数。最低桁数に満たない場合は、左側にゼロを付加します Function DecToHex(Dec As Long, Optional MinimumSize As Long) As String Dim result As String result = Hex(Dec) 'MinimumSize が未指定の場合は、ココで終わり If MinimumSize = 0 Then DecToHex = result Exit Function End If '16進の桁数が最低桁数を満たしている場合も、ココで終わり If Len(result) >= MinimumSize Then DecToHex = result Exit Function End If 'ゼロパディング処理行う Dim zeroString As String Dim i As Long For i = 1 To MinimumSize zeroString = zeroString + "0" Next i result = zeroString + result result = Right$(result, MinimumSize) DecToHex = result End Function
'16進数を10進数に変換 (単純に整数扱いとします) ' Hex:16進文字 Function HexToDec(Hex As String) As Long Dim HexLength As Long HexLength = Len(Hex) '右端から1文字づつ10進変換を行う Dim result As Long Dim i As Long Dim wkHex As String Dim wkValue As Long For i = HexLength To 1 Step -1 wkHex = Val("&H" + Mid$(Hex, i, 1)) wkValue = wkHex * (16 ^ (HexLength - i)) result = result + wkValue Next i HexToDec = result End Function
Is Nothing で可能である
例
Static ws対象シート As Worksheet If ws対象シート Is Nothing Then Set ws対象シート = ThisWorkbook.Worksheets("対象データのシート") End If
FileSystemFolder のメソッドを用いると、フォルダの中に、ファイルやフォルダがあっても、削除できる。
c:\aaa\aaa\bbb とあった場合、 c:\aaa\aaa を 削除した場合は、c\:aaa だけになる
Sub delete() On Error GoTo errhandler 'http://officetanaka.net/excel/vba/filesystemobject/filesystemobject.htm Dim objFSO As FileSystemObject Set objFSO = New FileSystemObject ' FSOによるフォルダ削除 objFSO.DeleteFolder "C:\aaa\aaa", True Set objFSO = Nothing Exit Sub errhandler: If Err.Number = 76 Or Err.Number = 70 Then MsgBox "削除失敗" Else Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile End If End Sub
最初に思いつく方式は
=IF(IsNA(VLOOKUP(〜)),"",VLOOKUP(〜))
であるが、VLOOKUP(〜)を2回書くのは、きれいじゃない。
方法1
結果が#N/Aの時は、ブランクや、指定した値が返却されるVBA関数で対応
Public Function VLookUpEx(検索値, 範囲, 列番号, NA時の値) As Variant On Error GoTo ERROR_HANDLER VLookUpEx = Application.WorksheetFunction.VLookup(検索値, 範囲, 列番号, 0) Exit Function ERROR_HANDLER: Select Case Err.Number Case 1004 'WorksheetFunction クラスの VLookup プロパティを取得できません。 VLookUpEx = NA時の値 Case Else Call Err.Raise(Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext) End Select End Function方法2
Public Function NA_VALUE(判定値, NA時の値) As Variant If Application.WorksheetFunction.IsNA(判定値) Then NA_VALUE = NA時の値 Else NA_VALUE = 判定値 End If End Function
何にでも使えて便利かも!
方法3
#N/A だけじゃなくって、何かエラーがあったら〜 IsErrorに対応した関数
Public Function ERROR_VALUE(判定値, ERROR時の値) As Variant If Application.WorksheetFunction.IsError(判定値) Then ERROR_VALUE = ERROR時の値 Else ERROR_VALUE = 判定値 End If End Function
Excel2003ベースの話
クラスにて、継承をする際、インターフェイスとしての継承しかできないので注意。
Object 型宣言による、動的バインドが現実解か。
オブジェクト指向プログラミングに関して、VBAで出来ないこと - だるまのエクセルVBA (uijin.com)
横1行の選択
Sub main() Sheet1.Cells.Rows(3).Select '同じ意味 Sheet1.Rows(3).Select End Sub
Rowsプロパティは Rangeオブジェクトを返却します
横 複数行の選択
Sub main() Sheet1.Rows(3 & ":" & 5).Select End Sub
選択状態の取得
Sub test() Dim str str = Selection.Address MsgBox str End Sub
選択範囲を調べる。選択範囲は、複数存在する可能性がある。上記の例では、二つ存在する。
Sub test() Dim r1 As Range Set r1 = Selection.Areas(2) MsgBox r1.Row & "-" & r1.Rows.Count & " " & r1.Column & "-" & r1.Columns.Count End Sub
名前がつけられているセルは、名前で参照する事ができる
このようにSheet1のB3 に 「なまえ」という名前をつけた
ソースから参照する場合は
Sub main() Dim str As String str = Sheet1.[なまえ].Text End Sub
この場合 [なまえ]はシート1に対して設定されている。sheet2に聞くと、sheet1の該当セルの内容が帰ってきてしまう。
シート1とシート2で 内容を管理しわけるようにするためには、以下のようにする
名前をつけるときに、シート名!名前 とつける
Sub main() Dim str As String str = Sheet1.[なまえ].Text '"あいうえお" が取得できる str = Sheet2.[なまえ].Text '"かきくけこ" が取得できる End Sub
VBAでスクロールパネル風の実装を行ってみた。
フレームを2個使って、スクロールーバーで内側のフレームを移動する方式。
VBA標準だけで組むと、マウスホイールが効かない
動的にボタンを複数生成したとき、イベント実装はクラス内で連携させる必要がある。
ボタンを三つ生成してみたときの例
UserForm1
ClassCommandButtonEvent
ClassObjectList
オブジェクトをArrayList Map のように管理するためのクラス
.Net 3.5 があれば、
Set oList =
CreateObject("System.Collections.ArrayList")
が使えるが、ココでは、標準の配列のみで実装してみた
動的にボタンを複数生成したとき、イベント実装はクラス内で連携させる必要がある。
ボタンを三つ生成してみたときの例
VBAでCallBack関数を実装する際、CallByNameメソッドが使える。
AddresOf 演算子は関数ポインタ的には使えない。
CallByName の第1引数には、オブジェクトが必要。なので、標準モジュールのメソッドはCalByNameメソッドでは呼び出せない。
呼び出しができるのは、フォームオブジェクト内のメソッドや、クラスのメソッドである。
以下の例は、フォームオブジェクト内での例である
Microsoft ActiveX Data Objects 6.1 Library への参照設定が必要