MW211 EXIT

devlog
ExcelVBA/シートの型
2018年06月11日
┌──────────────────────────────────────┐
│Dim シート As Worksheet                                                     │
└──────────────────────────────────────┘
基本的にはWorksheet型。

但し、配下のオブジェクト(ボタン)などを操作する場合には
Object型にしないとエラーとなるので注意。
┌──────────────────────────────────────┐
│Dim シート As Object   ' シート上のオブジェクトを操作                       │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/VLOOKUPの数値と文字列
2018年06月04日
入力元が数値で文字列セルに出力した場合、
検索値が、文字列でも数値でも
WorksheetFunction.VLookup()で該当なしとなってしまった。

ひとまず、入力元の数値をCStr()で文字列に変換した上で
文字列セルに出力したところ
検索値が、文字列でも数値でも
WorksheetFunction.VLookup()で該当あるとなった。

どうも、セルの書式と実体に(数値と文字列で)相違があると
該当なしとなってしまうようだ。
分類:ExcelVBA
ExcelVBA/CSVファイル出力
2018年06月02日
出力ファイルの選択を含めたCSVファイル出力処理は以下のような感じ。
┌──────────────────────────────────────┐
│Dim メッセージ As String, yMax As Long, y As Long                           │
│Dim 出力先 As Variant, ファイル名 As String                                 │
├──────────────────────────────────────┤
│ファイル名 = "CSVファイル.csv"  ' 初期表示                                  │
│Do                                                                          │
│    出力先 = Application.GetSaveAsFilename( _                               │
│        InitialFileName:=ファイル名, _                                      │
│        FileFilter:="CSVファイル,*.csv" _                                   │
│    )                                                                       │
│    ' キャンセル                                                            │
│    If 出力先 = False Then                                                  │
│        MsgBox "キャンセルされました。", vbInformation, "処理中止"          │
│        Exit Sub                                                            │
│    End If                                                                  │
│    ' 新規追加                                                              │
│    If Dir(出力先) = "" Then                                                │
│        Exit Do                                                             │
│    End If                                                                  │
│    ' 上書の確認                                                            │
│    ファイル名 = Dir(出力先)                                                │
│    メッセージ = ファイル名 & " は既に存在します。" & vbCrLf _              │
│               & "上書きしますか?"                                         │
│    If MsgBox(メッセージ, vbYesNo + vbExclamation, "上書確認") = vbYes Then │
│        Exit Do                                                             │
│    End If                                                                  │
│Loop                                                                        │
├──────────────────────────────────────┤
│Open 出力先 For Output As #1                                                │
│With ActiveSheet                                                            │
│    yMax = .UsedRange.Rows(.UsedRange.Rows.Count).Row                       │
│    For y = 1 To yMax                                                       │
│        Print #1, _                                                         │
│              Join(WorksheetFunction.Index( _                               │
│                       Range(.Cells(y, 1), .Cells(y, 16)).Value, _          │
│                       1, _                                                 │
│                       0), _                                                │
│                   ",")                                                     │
│    Next y                                                                  │
│End With                                                                    │
│Close #1                                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/範囲の値コピー最速
2018年03月24日
配列を介するのがよいようだ。
配列は二次元配列となるが、Variant型配列にすれば手軽に使える。

「入力」シートの左上3×3を、「出力」シートの左上3×3に値コピーする処理は
以下のような感じになる
┌──────────────────────────────────────┐
│Dim 配列 As Variant                                                         │
│With ThisWorkbook.Worksheets("入力")                                        │
│    配列 = Range(.Cells(1, 1), .Cells(3, 3)).Value                          │
│End With                                                                    │
│With ThisWorkbook.Worksheets("出力")                                        │
│    Range(.Cells(1, 1), .Cells(3, 3)) = 配列                                │
│End With                                                                    │
└──────────────────────────────────────┘

配列を介さず直接値コピーすることも可能。
┌──────────────────────────────────────┐
│Range(.Cells(4, 4), .Cells(6, 6)) = Range(.Cells(1, 1), .Cells(3, 3)).Value │
└──────────────────────────────────────┘
この方式では、異なるシート間でもコピーは可能だが
記述が煩雑となるので、異なるシート間の場合は、
配列を介した方がわかりやすいであろう
┌──────────────────────────────────────┐
│Range(出力シート.Cells(4, 4), 出力シート.Cells(6, 6)) _                     │
│= Range(入力シート.Cells(1, 1), 入力シート.Cells(3, 3)).Value               │
└──────────────────────────────────────┘
なお、配列に代入する際には「.Value」を省略できるが
範囲から範囲へ代入する場合には省略すると
値がコピーされない(何も起きない)ので注意。
分類:ExcelVBA
ExcelVBA/マクロ抜きシート複写
2018年02月28日
シートを複写すると漏れなくシートのマクロも付いてくる。
それを除去したいという場合、コピー後にマクロを削除するのは困難なようなので
(自由のソースコードを改変できることになり、セキュリティ的に厳しい)
新規シートを追加し、マクロ以外を地道にコピーする方が(遠回りだけど)近道なようだ。
以下その関数。
┌──────────────────────────────────────┐
│Sub マクロ抜きシート複写(ByVal 入力シート As Worksheet, _                   │
│                         ByVal 出力シート As Worksheet)                     │
│    Dim 改頁 As Variant, 表示倍率 As Long                                   │
│    '-----------------------------------------------------------------------│
│    '  コピー                                                               │
│    '-----------------------------------------------------------------------│
│    入力シート.Cells.Copy  ' コピー                                         │
│    With 出力シート.Cells(1, 1)                                             │
│        .PasteSpecial Paste:=xlValues   ' 値貼り付け                        │
│        .PasteSpecial Paste:=xlFormats  ' 書式貼り付け                      │
│        .Select                                                             │
│    End With                                                                │
│    '-----------------------------------------------------------------------│
│    '  印刷設定の複写                                                       │
│    '-----------------------------------------------------------------------│
│    Call 複写PageSetup(入力シート.PageSetup, 出力シート.PageSetup)          │
│    '-----------------------------------------------------------------------│
│    '  改頁位置の複写                                                       │
│    '-----------------------------------------------------------------------│
│    For Each 改頁 In 入力シート.HPageBreaks                                 │
│        出力シート.HPageBreaks.Add 改頁.Location.Rows                       │
│    Next 改頁                                                               │
│    '-----------------------------------------------------------------------│
│    '  表示倍率の複写                                                       │
│    '-----------------------------------------------------------------------│
│    入力シート.Select:  表示倍率 = ActiveWindow.Zoom                        │
│    出力シート.Select:  ActiveWindow.Zoom = 表示倍率                        │
│    '-----------------------------------------------------------------------│
│    '  クリップボードのクリア                                               │
│    '-----------------------------------------------------------------------│
│    Application.CutCopyMode = False                                         │
│    ' 上記で解消できないものは、全セル選択から一セル選択に変更で対応        │
│    ' →「図が大きすぎます。」エラー対策                                    │
│    入力シート.Cells(1, 1).Copy                                             │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Private Sub 複写PageSetup(ByVal 入力 As Object, _                           │
│                          ByVal 出力 As Object)                             │
│    With 出力                                                               │
│        .AlignMarginsHeaderFooter = 入力.AlignMarginsHeaderFooter           │
│        .BlackAndWhite = 入力.BlackAndWhite                                 │
│        .BottomMargin = 入力.BottomMargin                                   │
│        .CenterFooter = 入力.CenterFooter                                   │
│        .CenterHeader = 入力.CenterHeader                                   │
│        .CenterHorizontally = 入力.CenterHorizontally                       │
│        .CenterVertically = 入力.CenterVertically                           │
│        .DifferentFirstPageHeaderFooter = 入力.DifferentFirstPageHeaderFooter
│        .Draft = 入力.Draft                                                 │
│        .FirstPageNumber = 入力.FirstPageNumber                             │
│        .FitToPagesTall = 入力.FitToPagesTall                               │
│        .FitToPagesWide = 入力.FitToPagesWide                               │
│        .FooterMargin = 入力.FooterMargin                                   │
│        .HeaderMargin = 入力.HeaderMargin                                   │
│        .LeftFooter = 入力.LeftFooter                                       │
│        .LeftHeader = 入力.LeftHeader                                       │
│        .LeftMargin = 入力.LeftMargin                                       │
│        .OddAndEvenPagesHeaderFooter = 入力.OddAndEvenPagesHeaderFooter     │
│        .Order = 入力.Order                                                 │
│        .Orientation = 入力.Orientation                                     │
│        .PaperSize = 入力.PaperSize                                         │
│        .PrintArea = 入力.PrintArea                                         │
│        .PrintComments = 入力.PrintComments                                 │
│        .PrintErrors = 入力.PrintErrors                                     │
│        .PrintGridlines = 入力.PrintGridlines                               │
│        .PrintHeadings = 入力.PrintHeadings                                 │
│        .PrintNotes = 入力.PrintNotes                                       │
│        .PrintQuality = 入力.PrintQuality                                   │
│        .PrintTitleColumns = 入力.PrintTitleColumns                         │
│        .PrintTitleRows = 入力.PrintTitleRows                               │
│        .RightFooter = 入力.RightFooter                                     │
│        .RightHeader = 入力.RightHeader                                     │
│        .RightMargin = 入力.RightMargin                                     │
│        .ScaleWithDocHeaderFooter = 入力.ScaleWithDocHeaderFooter           │
│        .TopMargin = 入力.TopMargin                                         │
│        .Zoom = 入力.Zoom                                                   │
│        ' 以下省略(複雑なので)                                              │
│''''''''.Application = 入力.Application                                     │
│''''''''.CenterFooterPicture = 入力.CenterFooterPicture                     │
│''''''''.CenterHeaderPicture = 入力.CenterHeaderPicture                     │
│''''''''.Creator = 入力.Creator                                             │
│''''''''.EvenPage = 入力.EvenPage                                           │
│''''''''.FirstPage = 入力.FirstPage                                         │
│''''''''.LeftFooterPicture = 入力.LeftFooterPicture                         │
│''''''''.LeftHeaderPicture = 入力.LeftHeaderPicture                         │
│''''''''.Pages = 入力.Pages                                                 │
│''''''''.Parent = 入力.Parent                                               │
│''''''''.RightFooterPicture = 入力.RightFooterPicture                       │
│''''''''.RightHeaderPicture = 入力.RightHeaderPicture                       │
│    End With                                                                │
│End Sub                                                                     │
└──────────────────────────────────────┘
複写PageSetup()の部分(PageSetupオブジェクト配下プロパティの全コピー)が、
もっと簡単にできればいいのだが…。

オブジェクト配下プロパティの全コピーの方法はみつからないようだ。
分類:ExcelVBA
ExcelVBA/列幅の記録と呼出
2018年02月22日
非表示の「列幅保存用」シートを用意しておき、
以下のマクロでセーブしてロードする。
┌──────────────────────────────────────┐
│Sub 列幅セーブ()                                                            │
│    ActiveSheet.Cells.Copy                                                  │
│    ThisWorkbook.Worksheets("列幅保存用").Cells.PasteSpecial _              │
│        Paste:=xlPasteColumnWidths                                          │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Sub 列幅ロード()                                                            │
│    ThisWorkbook.Worksheets("列幅保存用").Cells.Copy                        │
│    ActiveSheet.Cells.PasteSpecial Paste:=xlPasteColumnWidths               │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA実験/コンストラクタで他クラスを実行
2018年02月15日
あるクラスのコンストラクタで他クラスを呼び出したら、どの順で実行されるか?
┌──────────────────────────────────────┐
│Public Sub 実験コンストラクタで他クラスを実行()                             │
│    Dim objクラス1 As New クラス1                                           │
│    Call objクラス1.実行                                                    │
│End Sub                                                                     │
├──────────────────────────────────────┤
│'クラス1.cls                                                                │
│Private Sub Class_Initialize()                                              │
│    Dim objクラス2 As New クラス2                                           │
│    Call objクラス2.実行                                                    │
│End Sub                                                                     │
│Public Sub 実行()                                                           │
│    MsgBox "②クラス1実行"                                                  │
│End Sub                                                                     │
├──────────────────────────────────────┤
│'クラス2.cls                                                                │
│Public Sub 実行()                                                           │
│    MsgBox "①クラス2実行"                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘
当たり前だが「コンストラクタ(→他クラスを実行)→自クラスを実行」の順で実行される
分類:ExcelVBA
ExcelVBA実験/LetとGet
2018年02月14日
次はLetとGetの起動タイミングをみてみよう
┌──────────────────────────────────────┐
│Private メンバ変数 As Long                                                  │
├──────────────────────────────────────┤
│Property Let 実験プロパティ(ByVal 入力値 As Long)                           │
│    メンバ変数 = 入力値                                                     │
│    MsgBox "①Letが実行された"                                              │
│End Property                                                                │
├──────────────────────────────────────┤
│Property Get 実験プロパティ() As Long                                       │
│    実験プロパティ = メンバ変数                                             │
│    MsgBox "②Getが実行された"                                              │
│End Property                                                                │
├──────────────────────────────────────┤
│Sub 実験LetGet()                                                            │
│    実験プロパティ = 777                                                    │
│    MsgBox "③" & 実験プロパティ                                            │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA実験/値渡し・参照渡し
2018年02月13日
今日から始まった実験シリーズ~!

まずは値渡しと参照渡しの違いを体感してみよう
┌──────────────────────────────────────┐
│Public Sub 実験値渡し()                                                     │
│    Dim 変数 As String                                                      │
│    変数 = "値渡し"                                                         │
│    Call サブ関数(変数)                                                     │
│    MsgBox 変数     ' →「値渡し」                                          │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Private Sub サブ関数(ByVal 変数 As String)                                  │
│    変数 = "参照渡し"                                                       │
│End Sub                                                                     │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│Public Sub 実験参照渡し()                                                   │
│    Dim 変数 As String                                                      │
│    変数 = "値渡し"                                                         │
│    Call サブ関数(変数)                                                     │
│    MsgBox 変数     ' →「参照渡し」                                        │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Private Sub サブ関数(変数 As String)                                        │
│    変数 = "参照渡し"                                                       │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/ボタン押下のApplication.Goto
2018年02月12日
「Application.Goto」命令で、特定のセルに飛んでも、
フォーカスがあたるだけで、アクティブ(セレクト)になる訳ではない場合ある。

つまり、ボタン押下のイベントで「Application.Goto」命令で
自シートのいずれかのセルに飛ぶと、飛ぶことはできるが
その後、キー操作を受け付けない(セルをダブルクリックするか何かしなければならない)

これは、アクティブなのがボタン(オブジェクト)側だからである。

これを解消する(アクティブにする)には、「Application.Goto」命令直後に
「ActiveCell.Select」など(*1)を実行すればよい。

*1:以下のいずれでもOK
  ・「ActiveCell.Activate」
  ・「ActiveCell.Select」
  ・「Selection.Activate」
  ・「Selection.Select」

なお、他シートへ飛ぶ場合には、
ボタンにフォーカスが当たっているのは自シート側なので
このような現象は発生しづらいが、直前のそのシートでボタンを押下しているなど
オブジェクト側にフォーカスが当たっていれば、同じ論理でキー操作を受け付けなくなる

例えば、二つのシートにボタンを配置し、
それぞれ他方の特定のシートに飛ぶようにした場合、
飛んだ先のシートではいずれもキー操作を受け付けないことになる

なお、オブジェクト側がアクティブになっている場合
画面左上の「名前ボックス」は空欄となっているのが目安となる。
分類:ExcelVBA
前へ 1 … 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 … 27 次へ