FC2ブログ

Excelじゆうちょう

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

記事更新カレンダー

10 « 2018-11 « 12
- - - - 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 -

やたらに多いカテゴリ

比較的新しい記事

新しいコメント

ありがたいブログ拍手

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

さみしいトラックバック

申し訳ないプロフィール

申し訳ない

管理人  [ 申し訳ない ]

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

RSSってなんぞ?

広告は消せないらしい

FC2Ad

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

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

        2012-09-30       ファイルとフォルダーの一覧作成

どれくらいぶりでしょうか、数えるのが怖いくらい久しぶりにExcel関連の記事を更新します。

テーマは、「ファイルとフォルダーの一覧を作成する」です。

この前、自分の画像ファイルを整理するのに自作してみました。
こんなの探せばわんさか出てきますが、たまにはExcelを触ってあげないとということで作成しました。

今回のポイントとしては、ファイルとフォルダーの一覧をコレクションオブジェクトに格納してから、まとめて出力しているところです。
こうすることで、一覧を取得しながら出力するよりも拡張性が高くなります。
まあ、拡張するつもりはありませんけどね。

詳しい解説は割愛しますが、いっぱいコメントを入れていますので、少しは参考になると思います。
ちなみに、このマクロはThisWorkbookオブジェクトで記述しています。

↓ブックを開くと、自動的に開始されます↓
ファイルとフォルダーの一覧作成、開始

↓フォルダーを黄色く出力↓
ファイルとフォルダーの一覧作成、終了


'コードウインドウ
Private Lng_row As Long '行番号

Private Sub Workbook_NewSheet(ByVal Sh As Object) '新しいシートを追加
main 'ここから開始
End Sub

Private Sub Workbook_Open() 'ブックを開く
main 'ここから開始
End Sub

'ここから開始
Private Sub main()
Dim Path_name As String 'パス名
Dim Flg_folder As Boolean 'ファイルかフォルダーか
With Application.FileDialog(msoFileDialogFolderPicker) 'フォルダーを選択するダイアログ
  If .Show = True Then 'ダイアログを表示、フォルダーを選択すれば
    Path_name = .SelectedItems(1) 'フォルダー名
    Select Case MsgBox(Path_name & Chr(13) & Chr(13) _
      & "このフォルダ配下の一覧を取得します。" & Chr(13) _
      & "フォルダーとファイルの一覧を取得しますか?" & Chr(13) _
      & "(「いいえ」を選択すると、フォルダーのみの一覧を取得します)", vbYesNoCancel)
    Case vbYes 'フォルダーとファイルの一覧
      Flg_folder = True
    Case vbNo 'フォルダーの一覧
      Flg_folder = False
    Case vbCancel 'キャンセルなら
      Exit Sub '帰る
    End Select
    Application.ScreenUpdating = False '画面更新をオフ
    Cells().Clear 'セルをすべてクリア
    Lng_row = 1 '1行目から入力していく
    Cells(Lng_row, 1) = Path_name 'フォルダー名入力
    Cells(Lng_row, 1).Interior.Color = vbYellow '黄色に塗りつぶし
    Lng_row = Lng_row + 1 '次の行
    getFolder Path_name, 2, Flg_folder 'フォルダー配下の一覧を取得
    Application.ScreenUpdating = True '画面更新をオン
  End If
End With
End Sub

'フォルダー配下の一覧を取得
Private Sub getFolder(Fol_path As String, Fol_level As Long, Flg_folder As Boolean)
Dim Clc_file As Collection, Clc_folder As Collection 'コレクションオブジェクト
Dim Var_for As Variant 'コレクションオブジェクトの要素はVariant
Dim File_name As String 'ファイル名
Set Clc_folder = New Collection 'コレクションオブジェクト作成、フォルダー用
Set Clc_file = New Collection 'コレクションオブジェクト作成、ファイル用

File_name = Dir(Fol_path & "\*", vbDirectory) 'フォルダーとファイル一覧
Do While File_name <> "" 'フォルダーかファイルがあれば
  If GetAttr(Fol_path & "\" & File_name) And vbDirectory Then 'フォルダなら
    If File_name <> "." And File_name <> ".." Then 'カレントフォルダーか親フォルダでなければ
      Clc_folder.Add File_name 'フォルダー名を追加
    End If
  Else
    If Flg_folder Then 'フォルダーとファイルの一覧なら
      Clc_file.Add File_name 'ファイル名を追加
    End If
  End If
  File_name = Dir() '次
Loop

For Each Var_for In Clc_file 'ファイル名をすべて繰り返し
  Cells(Lng_row, Fol_level) = Var_for 'ファイル名を入力
  Lng_row = Lng_row + 1 '次の行
Next Var_for
For Each Var_for In Clc_folder 'フォルダー名をすべて繰り返し
  Cells(Lng_row, Fol_level) = Var_for 'フォルダー名を入力
  Cells(Lng_row, Fol_level).Interior.Color = vbYellow '黄色に塗りつぶし
  Lng_row = Lng_row + 1 '次の行
  getFolder Fol_path & "\" & Var_for, Fol_level + 1, Flg_folder 'フォルダー配下の一覧を取得
Next Var_for

Set Clc_folder = Nothing 'コレクションオブジェクト作成、フォルダー用
Set Clc_file = Nothing 'コレクションオブジェクト解放、ファイル用
End Sub


こんなもんでどうかな?
スポンサーサイト

        2012-01-09       名前の削除

ブログ連続更新10日目、そろそろExcelの記事を書いておかないといけません。

今日のお題は、名前の削除。
セルに任意の名前をつけるあれ、[Ctrl]+[F3]キーのショートカットで編集できるあれです。

↓セル(1,1)に「Excelじゆうちょう」↓
セル(1,1)に名前

さて、このセルの名前ですが、自分では名前をつけていないのに知らない間にものすごく増えていたという経験はありませんか?
もしくは、編集を繰り返している間に参照が無効になって使えなくなった名前だらけになってしまったとか?

名前が増えたのはきっと、シートをコピーする際にそこに定義されていた名前をまるまる引っ張ってきてしまったからでしょう。
参照が無効になった名前を削除するには、名前の管理(旧Excelでは名前の定義)から削除しなければなりません。
これがなかなかめんどくさい。
新Excelでは複数選択をして一括削除ができるようになりましたが、旧Excelではひとつずつちまちま削除していかなければなりません。
旧Excelでひとつのブックを何度も使いまわして溜まりにたまったごみの名前の整理は、気が遠くなるほど面倒です。

いっそのこときれいさっぱりクリアにしてしまいましょう。

そのためのマクロが以下です。
※必要な名前が消えてしまう恐れがあるので注意


'【コードウインドウ】
Private Sub deleteNames1() '名前を全削除
Do While ActiveWorkbook.Names.Count > 0 '名前が定義されていれば
  ActiveWorkbook.Names(1).Delete '名前を削除
Loop
End Sub

Private Sub deleteNames2() '名前を全削除
Dim Obj_name As Name '名前オブジェクト変数
For Each Obj_name In ActiveWorkbook.Names 'ブックの名前の数だけ繰り返し
  Obj_name.Delete '名前を削除
Next Obj_name
End Sub


ふたつのマクロはどちらも同じ処理をしています。
処理速度だけなら下のほうが早いのでおすすめします。

上はというと、この名前はコレクションで管理されており、インデックスに注意してほしいと思って例をあげています。
名前のインデックスは一定ではなく、削除や追加によって変わってしまいます。
この辺りはVBAで操作でもしない限り気にする必要はないかと思いますが、VBAで管理してやろうと考える際には気をつけないといけません。

また、新Excelではブックに対して有効な名前かどうかを示すValidWorkbookParameterプロパティが追加されています。
これを使えば、不要な名前だけを削除する手助けになるかもしれません。
具体的には、参照が無効になった名前、シートのコピーで複製された名前、印刷範囲などが該当します。
もちろん、新規で登録する際に範囲をシートにしていてもこれに該当します。
(私が知っている範囲はこれだけです、もしかしたらほかにもあるかもしれません)

本当に必要な名前だけを、範囲をブックにして登録しておけば…ってちょっと制約が厳しいですね。
まあ、一応参考までにマクロを記載しておきます。


'【コードウインドウ】
Private Sub deleteNames3() '有効でない名前を削除
Dim Obj_name As Name '名前オブジェクト変数
For Each Obj_name In ActiveWorkbook.Names 'ブックの名前の数だけ繰り返し
  If Obj_name.ValidWorkbookParameter = False Then '有効な名前はここがTrue
    Obj_name.Delete '名前を削除
  End If
Next Obj_name
End Sub


旧Excelではこのプロパティはサポートしていませんのでご注意を。

        2011-01-17       \演算子の注意点

注意点というか、盲点というか、つい先日気付いてびっくりしたことです。

\演算子は除算の商を求めます。
7÷4を例にした時、
CLng(7 / 4)だと、1.75から端数が丸められて2が返り、
Int(7 / 4)だと、1.75から端数が切り捨てられて1が返り、
7 \ 4だと、1余り3から1が返ります。

これを見る限りでは、Int関数と\演算子は同じような動きをしています。
また、 速度比較、整数を取得 の記事で\演算子の方が(Excel2003上で)高速に動作することが確認されてますので、りっぷ2(りっぷつぅ)でもこれを多用しています。

ところが、Int関数と\演算子で結果が異なる場合があることが判明しました。
それは数値の小数部分を単純に切り捨てて整数に変換しようとした時、Int関数を使うよりも\演算子を使って1で除算した商をそのまま利用した方が速くなるんじゃないかと仮説を立てた時でした。

Int(0.8 / 1)の結果は、当然ながら0です。
0.8 \ 1の結果は、なんと1だったのです。

どうしてでしょう…答えはヘルプにありました。

【ヘルプより引用】
除算を実行する前に、数式はバイト型 (Byte)、整数型 (Integer)、または長整数型 (Long) の式に丸められます。

要するに、演算対象に小数が含まれていた場合、整数に丸められてから商を計算するというのです。
0.8 \ 1は計算前に1 \ 1と変換されていたため、1となったのです。

とすると、3.9 \ 1.24 \ 14すから、Int(3.9 / 1.2)3.253を期待してるとつじつまが合わなくなってしまいます。
ヘルプをちゃんと読んでなかった私がわるいんです。
あまり読みやすいものではありませんが、それだけ詳しい説明がされてるってことです。
いい教訓になりました。

それはそうと、今更気付いたこの動作、公開してるりっぷ2(りっぷつぅ)でやっちゃってないか心配です。
りっぷ2(りっぷつぅ)の前に公開していたlikePの方は大丈夫です。(お恥ずかしながら、\演算子を知ったのがりっぷ2(りっぷつぅ)からですので)
ペイントへの道ついでに、コードもしっかり見直さないと!

        2010-07-29       Split関数の代入先

ExcelVBAのSplit関数、今回はこの関数の代入について考えます。

Split関数は、第一引数に指定した文字列を、第二引数に指定した文字列を区切り文字にして、文字列型の配列変数を返します。

例えば、こんな感じになります。
Split("a,b1,c,d1e,1f1,g,f", "1,")の第一引数には、第二引数の"1,"が2ヶ所あります。
すると、{"a,b", "c,d1e", "f1,g,f"}のように要素数3が文字列配列を取得できます。
区切り文字は1文字でなくてもかまいません。

さて、これを代入する変数なのですが、当然ながら文字列型の配列変数でなければいけません。
しかも、引数によって配列の要素数が変わってしまいますので、文字列型の動的配列変数が必要になります。
動的配列変数とは、Dim Str_Array() As Stringのように、最初の宣言時に要素数を指定しない配列変数のことです。
対して、Dim Str_Array(0 To 5) As Stringのように、一般的な配列変数は、静的配列変数と呼びます。
もしくは、なんでも格納してしまうVariant型の変数でもOKです。

問題はここからです。
配列変数の定義は、Variant型でも可能です。
その場合、Split関数は使えるのでしょうか?
実際にやってみました。


'【コードウインドウ】
Private Sub testSplit()
Dim Str1 As String '文字列型の変数
Dim Str2() As String '文字列型の動的配列変数
Dim Str3(3) As String '文字列型の静的配列変数
Dim Var1 As Variant '万能型の変数
Dim Var2() As Variant '万能型の動的配列変数
Dim Var3(3) As Variant '万能型の静的配列変数

'Str1 = Split("a,b,c,", ",") '実行時エラー
Str2 = Split("a,b,c,", ",") '文字列型の動的配列変数ならOK
'Str3 = Split("a,b,c,", ",") 'コンパイルエラー
Var1 = Split("a,b,c,", ",") '万能型の変数ならOK
'Var2 = Split("a,b,c,", ",") '実行時エラー
'Var3 = Split("a,b,c,", ",") 'コンパイルエラー
End Sub


実際に使えるのは、文字列型の動的配列変数と万能型の変数だけでした。
(Var2()はいけると思ったんですけどねぇ)

それからもうひとつ、Split関数で繰り返し代入すると要素数はどうなるのでしょうか?


'【コードウインドウ】
Private Sub testSplitReDim()
Dim Str2() As String '文字列型の動的配列変数

ReDim Str2(10) As String '要素を再定義
  Debug.Print "インデックス: " & LBound(Str2) & " ~ " & UBound(Str2)
Str2 = Split("a,b,c,", ",") '要素数4を代入
  Debug.Print "インデックス: " & LBound(Str2) & " ~ " & UBound(Str2)
Str2 = Split("a,b,c", ",") '要素数3を代入
  Debug.Print "インデックス: " & LBound(Str2) & " ~ " & UBound(Str2)
Str2 = Split("a,b,c,d,e", ",") '要素数5を代入
  Debug.Print "インデックス: " & LBound(Str2) & " ~ " & UBound(Str2)
End Sub

【イミディエイトウインドウ】
インデックス: 0 ~ 10
インデックス: 0 ~ 3
インデックス: 0 ~ 2
インデックス: 0 ~ 4


代入の度にReDimされてるようなイメージですね、前の要素数は継承されません。
配列変数のインデックスは、ReDimステートメントのデフォルトと同じように0から始まります。

        2010-07-16       文字列表示の最大文字数

Excelのセルには、値や数式を入力することができます。
それらの値や計算結果が文字列なら左詰めで表示され、数値なら右詰めで表示されます。
日付や時間は、内部的にシリアル値という数値として扱われるため右詰めです。

そんなふうに文字列か数値かを自動判定してくれるExcelですが、しばしばおせっかいに感じることがあります。
項目番号に1と入力したら勝手に右詰めにされてしまった、「4/28」と入力したら「4月28日」と変換されてしまった、などなど。
要するに、入力したまま表示させたい場合です。

そんな時は、セルの書式設定から表示形式を変更します。
デフォルトでは「標準」となっており、これを「文字列」に変更することで、それ以降に入力する数値や数式が文字列として扱われるようになります。
(この表示形式には様々な種類がありますが、ここでは割愛します)

↓任意のセルを右クリックで設定可能↓
セルの書式設定

↓デフォルトは標準↓
表示形式(文字列)

↓すべて左詰め、数式もそのまま↓
表示形式比較

数値も数式も文字列扱いになりました。
それに際して、いくつか注意事項があります。
まず、数式でないので関数が使えません。
加えて、日付や時間は内部的にシリアルととして扱われなくなるため、計算が正しく行われなくなります。
そして今回の本題、文字列表示の場合、ひとつのセルに表示できる文字列の上限は255文字になります。

↓255文字までならOK↓
文字数:255

セル(1,1)だけ表示形式を文字列にしています、他は標準のままです。
文字の全角、半角は問いません、改行も1文字として計算されます。
(1行あたり50文字 + 改行1文字) * 5行分 = 255文字
今にもあふれてしまいそうです、ここに1文字追加すると…

↓257文字で########↓
文字数:256

これが標準なら問題なく表示されます。
ひとつのセルに長い文章を入力する場合、表示形式に注意が必要です。

古い記事  | HOME | 

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