エクセルVBA(シート選択のエラー処理)–(4)

作ったプロシャージャを動かして、シートを選択している様子です。リストボックスのシート名をクリックすると、クリックしたシートに移動します。

どのシートが選ばれたかは、リストボックスの IndexID でわかります。Worksheets( IndexID).Name で、選択されたシート名を表示できます。それほど使う場面はないかとは思いますが、使う時は、便利な機能のよ
うな気がします。

エクセルVBA(シート選択のエラー処理)–(3)

以下は、VBA 標準モジュールに記載したプロシャージャです。
Sub ボタン2_Click() は、シートに貼り付けてある、マクロ起動用のものです。
Function sheets_set(Wb As Workbook) の中身は、本来ユーザーフォームの _Initialize()の項目に記入すべきでしょうが、Wb の引き渡し方法がわからないので、こちらに書きました。

---------------
Sub ボタン2_Click()
  Call Select_sheet
End Sub
---------------
Function Select_sheet()
  ‘====読み込みフルパスファイル名の取得====
  Dim fPath As Variant
  Dim fType, prompt As String

  fTyp = “Excelファイル(*.xlsm),*.xlsm,Excelファイル(*.xlsx),*.xlsx,Excelファイル(*.xls),*.xls”
  prompt = “Excelファイルを選択してください”
  fPath = Application.GetOpenFilename(fTyp, , prompt)

  If fPath = False Then
    MsgBox “ファイルが選択されていません。”
    Exit Function
  End If

  ‘====読み込みのファイル名取り出し====
  Dim STR As String
  Dim t_file_name As String

  STR = StrReverse(fPath)
  t_file_name = Right(fPath, InStr(STR, “\”) – 1)

  ‘====ファイルを開く処理====
  Dim Wb As Workbook

  If ThisWorkbook.FullName <> fPath Then
    If fPath <> “” Then

    For i = 1 To Workbooks.Count
      If Workbooks(i).Name = t_file_name Then
        BookFlag = True
      End If
    Next i

    If BookFlag <> True Then
      MsgBox “ファイルを開きます。”
      Set Wb = Workbooks.Open(fPath, UpdateLinks:=Ture, ReadOnly:=Ture)

      Call sheets_set(Wb)
      UserForm1.Show vbModeless
    Else
      MsgBox “すでに開いているファイルを開こうとしてます。”
      Exit Function
    End If
    End If
  Else
    MsgBox “自分自身を開こうとしてます。”
    Exit Function
  End If
End Function
-------------------------------------------
Function sheets_set(Wb As Workbook)
  Dim i As Integer

  With UserForm1.ListBox1
    ‘一つだけ選択
    .MultiSelect = fmMultiSelectSingle
  End With

  For i = 1 To Wb.Worksheets.Count
    UserForm1.ListBox1.AddItem (Wb.Worksheets(i).Name)
  Next

  UserForm1.ListBox1.ListIndex = 0
End Function


以下は、ユーザーフォームの方に記載したものです。

-------------------------
Private Sub CommandButton1_Click()
  ThisWorkbook.Activate
  Unload UserForm1
End Sub
-------------------------
Private Sub ListBox1_Click()
  sh_name = ListBox1.List(ListBox1.ListIndex)
  TextBox1.Text = sh_name
  Worksheets(sh_name).Activate
End Sub
----------------------------------------------
Private Sub ListBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  If KeyCode = vbKeyReturn Then
    KeyCode = 0
    ThisWorkbook.Activate
    Unload Me
  End If
End Sub
----------------------------------------------
Private Sub UserForm_Initialize()
  With ListBox1
  ‘一つだけ選択
  .MultiSelect = fmMultiSelectSingle
  End With
End Sub

エクセルVBA(シート選択のエラー処理)–(2)

エラー処理2・・・・自分自身を開こうとする。

  このエラー処理は、自分自身を開くとまずいので、ThisWorkbook.FullName と 開こうとするファイ
  ルのフルパスの fPath を比較することで、同じなら、「自分自身を開こうとしてます。」のメッセージ
  を出して、Function  を抜け出します。

  If ThisWorkbook.FullName <> fPath Then
    
    ・*開こうとするファイルとすでに開いているファイルを比較する。
    
  Else
    MsgBox “自分自身を開こうとしてます。”
    Exit Function
  End If

  次の処理のファイルを比較するに先立ち、開こうとするファイルのファイル名を取り出しておきます。い
  くつか方法をためしましたが、文字列を編集する方法がいいみたいで、フルパスを文字の後尾から ”¥” 
  を探してファイル名を取り出します。緑の”¥”を探しだせば、赤のフィル名を取り出せます。

    E:¥VBA開発¥シート選択Dummy.xlsx
                  ←←←←←

  はじめ、InStrRev を使ってみましたが、思った結果がでなかったので(後でわかりました)文字列を反転
  して、先頭から”¥”の探し出し、その文字のある手前まで切り出して、ファイル名を取得しました。なん
  と、InStrRev 関数は、後ろから文字を探すのですが、見つけた場所の位置を、後ろから数えた位置では
  なく、前から数えた位置を返すみたいでした。下記のようにして  t_file_name にファイル名を取り込
  みました。
  ‘====読み込みのファイル名取り出し====
   Dim STR As String
   Dim t_file_name As String

   STR = StrReverse(fPath)
   t_file_name = Right(fPath, InStr(STR, “\”) – 1)

エラー処理3・・・・既に開いているファイルを開こうとする。
  既に開いている Book数を Workbooks.Count で取得して、For ループの中で、開こうとしている
  ファイル名と比較し、同名のファイルがあれば、True を そうでなければ False をセットして判定し
  ます。開いているファイル名は、Workbooks(i).Name で取得できます。
  False の場合だけ(同じファイルがない),目的のファイルを開き、Call sheets_set(Wb) で、取得する
  シート名をユーザーフォームのリストボックスに、セットします。

  For i = 1 To Workbooks.Count
    If Workbooks(i).Name = t_file_name Then
      BookFlag = True
    End If
  Next i

  If BookFlag <> True Then
    MsgBox “ファイルを開きます。”
    Set Wb = Workbooks.Open(fPath, UpdateLinks:=Ture, ReadOnly:=Ture)

    Call sheets_set(Wb)
    UserForm1.Show vbModeless
  Else
    MsgBox “すでに開いているファイルを開こうとしてます。”
    Exit Function
  End If

エクセルVBA(シート選択のエラー処理)–(1)

お手伝いでしている仕事がらみの作業用に、何年かかけて、VBAのプロシャージャを作成しました。おかげ様で、短い時間でその処理ができるようになりました。

ただ、時々でるエラーを、その都度修正したりしながら、使ってきました。自分で作成したプロシャージャなので、なぜエラーが起こったのか、ちょっと流れを見ればわかるのですが、なるべく直さなくてもいいように、作り直したいなと思ってました。

やっていることは至極簡単なことですが、手作業でやると結構な時間とられるので、どうしても、プロシャージャが必要でした。継ぎ足し継ぎ足ししてきたので、結構な分量のプロシャージャになってしまってますので、全部作り直すことは、なかなかできないのですが、ある作業の一部分だけでも、考えられるエラーについての対処を十分にできるようにしたいなと、手直しをし始めました。

今回、作業の対象にしたので、他のエクセルブックを選択して開きそのブックのシートを選択する、という部分のプロシャージャです。今日、一日、かかって、ほぼ、できたので、備忘録がてら、記載します。

エラー処理1・・・・存在しないファイルを開こうとする。
  このエラーの回避は、GetOpenFilename を使って、それそれのディレクトリーを開いて、これから開こ
  うとするファイルを選択して開くということで、回避しました。ただこの画面で、キャンセルを押してし
  まうと、「ファイルが選択されてません。」のエラーとなりプロシャージャが中断してしまい、fPath に
   False がセットされますので、IF 文でFunction を抜け出すことで、回避しました。

  ‘====読み込みフルパスファイル名の取得====
   Dim fPath As Variant
   Dim fType, prompt As String

   fTyp = “Excelファイル(*.xlsm),*.xlsm,Excelファイル(*.xlsx),*.xlsx,Excelファイル(*.xls),*.xls”
   prompt = “Excelファイルを選択してください”
   fPath = Application.GetOpenFilename(fTyp, , prompt)

   If fPath = False Then
     MsgBox “ファイルが選択されていません。”
     Exit Function
   End If

 

Windows10アップデート失敗

いままでは、なかったのですが、昨日、Windowsのアップデートに失敗したようで、結局、Windowsの初期化を余儀なくされました。
 原因はよくわからないのですが、不安定なネット環境(iPhoneのテザリング接続)であれこれやっている状態で、アップデートのフィルが一部こわれた状態で保存されたのでは、と想像してます。
アップデートを先送りしてもよかったのですが、アップデートがサポート期間とも関係があるようなので、アップデートするべくもがきました。そのうち、何度も同じ状態を繰り返すPCの状態になり、Windowsが立ち上がらなくなりましたので、

ここを参考に

初期化をしました。
一時、苦労して作ったエクセルVBAスクリプトが心配で、一時真っ青になりかかりましたが、ファイル当は引き継いで初期化できるとのことで、一安心。また、慌てて、何か所かにバックアップをしました。
大事なファイルはぶじだったのですが、firefoxのブックマークがなくなったのがちょっとでした。別なPCのブックマークをエクスポート後、インポートして、完全ではないのですが、ほぼ使ってたものを再現できました。 「追記」 セットアップが終わると、削除.htmlみたいな名前のファイルが作成されてました。どうやら、既存のシステムから新しいシステムをインストールするにあたって、削除されたプログラムの一覧が記載されているようでした。気になっていたソフトがあったので、そのこ項目をクリックしたら、なんと、ウイルスが存在していたHPにアクセスしたようで、スクリーンがロックされてしまって、サポートまで、電話しろという画面が表示されてしまいました。

と同時に「あなたな個人情報のIPアドレスがなんちゃらかんちゃら」と音声の案内まででてきました。ちょっとあせりましたが、電源を切っても変化ないので、Ctrl+Alt+Dele を同時に押して、タスクマネージャを表示させると、Fire-Foxだけが動いてました。クリックしたリンク先にこのしょうもないものが設置されているようでしたので、Fire-Fox をクリックした後、タスクの終了をクリックして、終了させました。念のため、

Microsoft Defender

でフルスキャンをししまた。幸い、異常はありませんでした。このしょうもないものを表示させるプログラムも、自分のPCが動かしているので、自分のPCの方でプログラムを止めてしまえば、いいのですが、なかなかできませんよね。幸い、タスクマネージャーのことを知っていたので、この対応ができましたが・・・・。

これで、ウインドウ内の「ここをクリック」などと表示してあるところを、クリックしたりすると、さらに悪意のあるプログラムをインストールされることになるんでしょうね。クワバラ、クワバラ。

PHPヴァージョンアップ備忘録

旧の掲示板は,「画像掲示板plus」というPHPで書かれたものを使ってました。このプログラム(スクリプト)は,「LEMON-S PHP」というHPに掲載されていたものです。あまり需要がないのか,更新が途絶えているようで,サポート掲示板も,2016年の作者の書き込みを最後に,更新されてないようです。2016年は,PHP7になった頃でしょうか,サポートにもPHP7で「画像掲示板plus」を動かすにはどうすればいいか,ちょっとだけ記述がありました。
この旧掲示板は,私にとってもいろいろな情報が残ってるので,表示だけは残したかったので,PHPの初心者の私が,ネットサーフィンをたよりに,V5⇒V7にアップデートしても動くように,無謀な挑戦をしたところです。
「LEMON-S PH」には,まだ,PHPのスクリプトが残ってますので,2015年に更新されたv2.36をDLしました。このファイルは,このままだと文字化けを起こしますので,

    SHIFT-JIS⇒⇒UTF-8

のように変換して,保存しました。また,サーバー上に残ってる,「imglog.log」というCSV形式のデータもUTF-8で保存しなおしました。
一方,最低限必要なPHPとアパッチをどうするか迷いましたが,それぞれにインストールすると細かい設定が面倒そうで,デバック環境を作るだけでも時間がかかりそうなので,諸兄のHPを見ながら,「XAMPP」という,PHPプログラム作成の環境を一括インストールで作成できるものを導入しました。

導入後早速その環境で,該当するプログラムを動作させ,あれこれ始めました。また,公開しているHPのようにまっしろかなと思いましたが,

    Warning: Use of undefined constant

という警告が20以上でてきました。

意味がわからなかったのですが,ネットくぐってみると,該当の行の該当の項目に「’ ‘」の記述がないことが原因であることがわかりました。そこで,

    修正前・・・・・・define(LOGFILE, ‘imglog.log’);
    修正後・・・・・・define(‘LOGFILE’, ‘imglog.log‘);

のように変更しました。defineの括弧の後半(赤字部分)が数字の場合,シングルクーテーションがあるところとないところがあり,その違いが分かりませんでしたが,下記のように統一しました。

    修正後・・・・・・define(‘MAX_KB’, 500)

これで,「Warning」はほとんどなくなりました。PHP5では,このシングルクオーテーションがなくても,きちんと動いてた様で,PHP7では,そのチェックが一層厳しくなったそうで,この結果になってるようです。

まだ消えないエラー表示を見てみると

    Fatal error: Uncaught Error: Call to undefined function eregi()

というのがあり,これも調べてみると,PHP5で使われていた備え付けの関数がPHP7では,廃止になったとのことで,代替えの関数として,

    preg_match

が使えるとのことなので,

    修正前・・・・・・eregi($value,$ref)
    修正後・・・・・・preg_match(‘/$value/i’,$ref)

のように変更。このFatal error:があるとプログラムはそこで,止まってしまうようで,もう一カ所修正箇所がありました。

修正前・・・ereg_replace(“(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)”,”<a href=\”\\1\\2\” target=\”_blank\”>\\1\\2</a>”,$proto);
修正後・・・preg_replace(“/(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)/“,”<a href=\”\\1\\2\” target=\”_blank\”>\\1\\2</a>”,$proto);
再修正・・・preg_replace(“/(https?|ftp|news)(:\/\/[[:alnum:]\+\$\;\?\.%,!#~*\/:@&=_-]+)/”,”<a href=\”\\1\\2\” target=\”_blank\”>\\1\\2</a>”,$proto);

 

修正後,懐かしい画面の片割れがでてきましたので,ここでも少し「やった。」になりました。懐かしい画面と一緒にでてきたのは,書き込みの表題だけでした。

修正したものを見ると,再修正が必要で,最終的に,青で示したエスケープシーケンスを挿入すると,コメントまで表示できました。

PHP側で,正規表現のはじめ「/」と,終わのりを意味する「/」の他にあるスラッシュを区別する必要があり,区切りでないスラッシュは,「¥/」とする必要がありました。

表題・コメントが表示できたのはいいのですが,それと同時に大量のNOTICEがでてきました。

   Notice: Undefined variable: r_com

調べてみると,定義してない(NULL)状態の変数に操作をしているために起きるようで,それぞれの変数の直前に

    r_com=””

という記述で,変数は空(何も入ってないですよということらしい)ということを代入して,このNotice:を消しました。

その後,どうしても画像を表示できず,画像を操作していると思われるところを一つ一つ確認していきました。結局,WINDOWSの環境でデバックをしていましたので,ドライブの指定が間違っていて,小文字を大文字に変えたら,あっけなく表示できました。思わず,そばにいた妻に「やっった。」と叫んで,そのわけを説明しました。という訳で長い道のりでしたが表示だけできました。

でも,どうしても消せないNotice:があるので,あれこれこも調べましたが,プログラムで表示させなくできるということで,PHPのファイルの冒頭に,

error_reporting(E_ALL & ~E_NOTICE);

を記入することで,消すことにしました。しかし,消してみると新たに,

Deprecated: Function get_magic_quotes_gpc()

というエラー出てきました。これも調べてみると,PHP7では,実装されてなくて,常にFALSEを返すということで,該当の部分には,

 if(get_magic_quotes_gpc()) $gazoubbs = stripslashes($gazoubbs);

のような記述で,get_magic_quotes_gpc()が有効なら$gazoubbs = stripslashes($gazoubbs)を実行するということでした。常にFALSEを返すことから,$gazoubbs = stripslashes($gazoubbs)は実行されないので,ここは,削除することにしました。

これで,やっと,エラーも表示されなくなり,閲覧だけできるようになりました。

{追記}PHPのプログラムを追っていくなかでいくつか分からない表現にであいました。
      .$value.
    のような表現で,これも調べてみると,文字の結合を表す表現でした。分かったのもありますが,
        $dat.=’     のような表現が所々に,あり,このシングルクオ-テンションの意味が未だに不明です。単に$datに    「`」を結合するものなんでしょうか。

---本家のBlogn+が閉鎖に---

 このブログの本家というか,このブログのプログラムの大本が
 閉鎖になりました。
 何年か前から,更新がなく,どうしたのかなと思っていました。
 
 しばらくは,このまま使っても大丈夫だと思いますが,Windowsと
 かのアップデート等で,不具合がでてもこまるので,ぼちぼち
 他のシステムに乗り換える必要がありそうです。
 使う条件が,システムを自分でいじれることと,基本,無料が
 条件です。
 ネットをあさってみると,
    WordPress
    Movable Type
 あたりが適当なようですが,このブログを動かしている
 サクラのサーバーでは,WordPressが標準で簡単にインストール
 できるようになっているので,それを使ってみようかなと思います。
 乗り換えにあたっては,
      今までのブログをそっくり移行する
      今までのブログはそのままに新しい記事を移行する
 等でしょうが,ある時期をさかいに移行するのは,難しそうなので,
 とりあえず,平行して,徐々に,移行しようかなと思います。
 そのために,いろろ情報を収集します。

---Windows10の起動時のナンバーロック---

 久しぶりにWindows10の設定を見直しました。
 といっても,起動時にテンキーが使えないが不便で,前にも
 設定をしたのですが,ナンバーロックがされないままで,
 立ち上がる状態でした。
 久しぶりに検索をしましたら,諸兄のHP
 に行き着いて,
   
  1 regeditを起動
  2 HKEY_USERS \ .DEFAULT \ Control Panel \ Keyboard を開く
  3 「InitialKeyboradIndicators」の値を「2147483650」に変更する。
  4 regeditを終了する。

 をやればいいとのことでしたので設定を変更いたしました。
 結果,大丈夫でした。
 前にもここいじったことあるみたいでしたが,
   「InitialKeyboradIndicators」
 の値が,
   2147483650
 ではなくて
   2147483648
 でした。
 起動時のパスワードの入力にテンキーが使えます。

“---Windows10の起動時のナンバーロック---” の続きを読む

---お買い得プリンター---

 本日あるお祭りに行ってまいりました。
 大勢の方が参加してましたが,出店?もいくつかでてました。
 その中のテントで,バザーをやってましたので,物色してみると,
 レーザープリンターが2000円ででてました。
 LBP6030というレーザープリンターです。

 

 ジャンク品かはたまた中古かなと思って購入しました。
 動けば,トナーを購入すれば使えるかなと思いトナーの値段を
 調べると約4700円と,本体よりも高いです。
 家に持ち帰り,梱包を解いてみましたが,びっくりしました,
 なんと新品でした。

 

 ネットで値段を調べてみると販売価格が9400円から
 10000円前後です。いい買い物をしました。

WINDOWS10の修復

 知人の息子のWINDOWS10のPCが立ち上がらなくなった
 の見てほしいいとの依頼をうけました。
 最初,セーフモードで立ち上げて,修復すればいいかなと
 安易に考えていましたが,どうやらブートローダー?部分
 が破損しているらしく,だめでした。
 そこで,いろいろ試みましたが,上書きインストールをする
 ことにしました。
 預かったPCには,リカバリー領域があるようで,これを
 使えば工場出荷時の設定にもどると思いますが,
 データが消えてしまうのでやめました。
 もうWINDOWS10への無償アップデートは終わったのか
 と思いましたが,まだここからアップデートできるようです。
 これまた,諸兄のHPを参考に,USBメディアからアップデート
 できるように作成しました。
 こまったのが私と家内のPCはPROエディションで,これで作成
 すると知人の息子のPCはHOMEエディションなので,プロダクト
 キーの要求をされるということでしたので,これまた,知人から
 PCをかりて(幸い知人のはHOMEエディションでした。)作成
 しました。
 インストールにあたっていくつかバリエーションがありましたが,
 以前のものに戻すことはできなくて,当初の予定通り上書き
 インストールしました。
 終了後,旧OSのフォルダーができていて,そこに,以前のもの
 と思われるデータがありました。
 めでたしめでたしです。手紙を添えて,明日にでも知人に届け
 ます。