日経BP-IT PRO Activeの記事を印刷用にするブックマークレット
もくじ
- 前置き
- 環境
- ソース
- 使うとどうなるか
- 感想
前置き
最近チーム全体が情報収集する気風になってきていて、日経関連の記事を見る機会が多くなりました。
PDF込みで記事になっていたり、印刷ビューになるものはいいのですが、それ以外はページ全体を紙に印刷して情報共有することになっています。
で、毎度開発者ツールで無駄なものを削除していたのですが、面倒なのでブックマークレットにしてみました。
「ブックマークレットとはなんぞや」についてはググってください。
環境
以下の環境で動かしてます。
ソース
本業じゃないのでおそらく美しくないコードになっています。
javascript: (function() { ["#bpGlobalHeader","#wrapper>header","#wrapper>footer","#wrapper>div>aside",".content>article>footer>section",".tools",".breadcrumb"].forEach(function(val, index, ar) { Array.from(document.querySelectorAll(val), e => e.remove()); }); document.querySelector("article").style.width="auto"; })()
使うとどうなるか
実行前
実行後
感想
- 他の日経のサイトで試したら全然消えなくて辛い。
- Javascriptの簡潔な組み方が分からない。
- ブックマークレット割と便利。
Outlookのクイック操作のエクスポート/インポートをする方法
もくじ
- 前置き
- クイック操作のエクスポート
- クイック操作のインポート
- 注意点
前置き
日本語でググると古い記事がトップに出て エクスポート不可能 という結論になり、 英語でググると新しい記事がトップに出て エクスポート可能 という結論にになるという切ない感じだったので書きました。
「outlook クイック操作 エクスポート」 とかググったら一番目に下記URLがヒットします。 2011年の古い記事なのですが、結論としてはエクスポート不可ということになっています。
Microsoftコミュニティ-作成したクイック操作の設定をエクスポートしたい
作成したクイック操作の設定をエクスポートしたい - マイクロソフト コミュニティ
「outlook quick step export」とググれば今年の記事が出てきます。 結論としては ツールを使えば可能 とのこと。
How can I export quick steps
How can I export quick steps - Microsoft Community
やっぱり日本語の情報だけでなく英語でもググる必要がありますね。 クイック操作は英語でquick stepと呼ぶそうです。Officeの日本語から英語で検索する時に下記の記事が参考になりました。
クイック操作のエクスポート
mfcmapi のダウンロード
mfcmapiというツールを使用します。 下記URLから最新のバイナリをダウンロードします。 古いバージョンだと日本語(マルチバイト文字)が正しく扱えず、文字化けします。
mfcmapiによるエクスポート
英語の記事と同様の手順となりますが、
- [Session]->[Logon] を選択する。
- 自分のメールアドレスをダブルクリックします。
- [Root Container]先頭の三角をクリックして開く。
- [インフォメーション ストアの先頭]先頭の三角をクリックして開く。
- [クイック操作設定]を右クリックして[Export Folder]->[AS MSG files...]
- 出力先のディレクトリを指定して、エクスポート完了
クイック操作のインポート
mfcmapiによるインポート
- [Session]->[Logon] を選択する。
- 自分のメールアドレスをダブルクリックします。
- [Root Container]先頭の三角をクリックして開く。
- [インフォメーション ストアの先頭]を右クリックして[Open associated contents table]を選択。
- [Folder]->[Import]->[From MSG...]を選択肢、インポートするMSGファイルを指定する。
- インポート完了
注意点
検証の前提
- マシン環境
- Windows 7 32bit
- Office2010
- MFCMapi.exe.17.0.17099.01
- 試した事
- 自分のPCから[エクスポート]->[クイック操作削除]->[インポート]
- 自分のOutlook2010からエクスポートしたクイック操作を他のOutlook2013にインポート
念のためクイック操作を複製したり、消えても問題ないクイック操作でお試しすることを推奨します。
PowershellでCSVをExcelファイルに転記する
状況
DBの特定のテーブルをちょっと結合したりなんかして特定フォーマットのExcelに出力して欲しい
こんな要件が結構あります。
私が入る前はこんな感じの要件1つに付き1つアプリ組んでたんですね。
今回そんな感じのを頼まれたので、できるだけアプリを組まないようにスクリプトで完結させました。
本記事はその時の成果物です。
転記ツール
構成
- Csv2Excel.ps1
- /lib
- EPPlus.dll
フォルダ構成書きにくい。 今回EPPlusを使っていて、理由は以下です。
- 以前PowershellでComObjectからExcelを使ったところ、色々やってもプロセスが消えなかった。
- サーバー上でロックしている状態で動くので、Comの方のExcelを使うと正常に動かない。
スクリプト
引数
引数名 | 説明 |
---|---|
sourceDataPath | CSVのパス |
templatePath | テンプレートとなるファイルのパス |
destinationPath | 出力先パス |
configPath | 設定ファイルのパス(json) |
設定ファイル
バッチからPowershellスクリプトを実行するので、列になるオブジェクトやバッチ本体を修正せずに調整したい項目はjsonにしました。
{ "delimiter":",", # 区切り文字 "start_location": { # 開始位置 "row": "2", "column": "1" }, "numeric_columns": [10,11] # 数字のカラム(Stringそのまま入れたくない場合指定) }
ソースコード
param( [parameter(mandatory=$true)][string]$sourceDataPath, [parameter(mandatory=$true)][string]$templatePath, [parameter(mandatory=$true)][string]$destinationPath, [parameter(mandatory=$true)][string]$configPath ) <# ライブラリ参照 #> [System.Reflection.Assembly]::LoadFrom((Join-Path (Split-Path $MyInvocation.MyCommand.Path) "\lib\EPPlus.dll")) | Out-Null <# 設定ファイル読む #> $cfg = Get-Content -Path $configPath -Raw | ConvertFrom-Json <# Excelのフォーマットに転記して、出力先に名前を付けて保存する #> $pkg = New-Object OfficeOpenXml.ExcelPackage -ArgumentList $templatePath $sht = $pkg.Workbook[0].Worksheets[1] $csvRows= Get-Content -Path $sourceDataPath -Encoding Default for($ri=0; $ri -lt $csvRows.length; $ri++) { $csvRowData = ($csvRows[$ri]) -split $cfg.delimiter for($ci=0; $ci -lt $csvRowData.length; $ci++) { $row = $ri + $cfg.start_location.row $col = $ci + $cfg.start_location.column $value = if($cfg.numeric_columns.Contains($col)){ [double]($csvRowData[$ci]) } else { [string]$csvRowData[$ci] } $sht.Cells.Item($row, $col).Value = $value } } $pkg.SaveAs($destinationPath) $pkg.Dispose()
以上!
情報リテラシーとは何か。英国図書館情報専門家協会の記事を参考に。
新入社員の教育のため、「情報リテラシー」というネタが振られたので、調べてみました。
参考にしたのは information literacy meaning でググってヒットした CILIP(英国図書館情報専門家協会)の記事です。
以下、下手っぴ翻訳で読んだ内容を書いていきます。
曰く、情報リテラシーの定義は以下のようです。
Information literacy is knowing when and why you need information, where to find it, and how to evaluate, use and communicate it in an ethical manner.
自分の中で翻訳したのが以下(間違ってるかも)
情報リテラシーとは、いつ・なぜ情報が必要か、どこで見つけるか、どうやって倫理的な方法で評価・使用・伝達するか、を知る事です。
続けて情報リテラシーのわかる人になるための必要な理解についても記載されています。
以下の項目への理解が必要だそうです。 ・情報の必要性 ・使用できる資源 ・情報の見つけ方 ・結果を評価する必要性 ・結果を利用する方法 ・使用における倫理や責任 ・発見したものを伝達・共有する方法 ・発見したものを管理する方法
これらの項目の詳細は「Related Documents」のPDFファイルに記載されています。
https://www.cilip.org.uk/sites/default/files/documents/Information%20literacy%20skills.pdf
曖昧になっていた言葉の定義を調べる事である程度腑に落ちたかなと思いました。
SQL ServerのDBの全テーブルをエクスポート/インポートしちゃうバッチ。
開発機でDBを空にしたり戻したりめっちゃ面倒なので作ってみました。
バッチ
エクスポートするバッチ
ExportAllTables.bat
ソースコード
@echo off setlocal pushd %~dp0 :-------------------------------------------------------------------------------- : 概要:対象データベースの全テーブルをエクスポートする。 : 引数: : %1-対象のサーバー : %2-対象のデータベース名 : 特記事項:サーバーへのアクセスは信頼関係接続で行う。 :-------------------------------------------------------------------------------- :-------------------------------------------------------------------------------- : 変数 :-------------------------------------------------------------------------------- : Powershellで日付の文字列[yyyyMMdd_HHmmss]取得 powershell -Command "echo (Get-Date).ToString('yyyyMMdd_HHmmss')" > %temp%\dayvalue set /p ymd=< %temp%\dayvalue : DB設定 set Server=%~1 set DB=%~2 : 引数チェック if "%Server%"=="" ( exit /b 1 ) if "%DB%"=="" ( exit /b 2) : サーバー名の指定 [\\SERVER\INSTANCE] 形式でフォルダ名にできないので [SERVER.INSTANCE]形式に変更する powershell -Command "'%Server%'.Replace('\\','').Replace('\','.')" > %temp%\serv set /p ServerFolderName=< %temp%\serv : 保存先フォルダ(サーバー名とデータベース名で基底のフォルダを作る) set BaseDir=%ServerFolderName%-%DB%\ set SaveDir=%BaseDir%%ymd%\ : 対象DBのテーブル一覧 set TableList=TableList.txt :-------------------------------------------------------------------------------- : メイン処理 :-------------------------------------------------------------------------------- mkdir %BaseDir% mkdir %SaveDir% : 対象DBのテーブルのリストを取得 bcp "select name from %DB%.sys.tables" queryout %TableList% -S%Server% -T -c -t; > nul : 出力したテーブルのリストから1行ずつバックアップする。 for /f "delims=" %%i in (%TableList%) do ( call :ExportTable "%Server%" %DB% %%i "%SaveDir%" ) : テーブルリストを出力先に移動する。 : ※サーバーを(local)で指定された場合に、テーブルリストのパスがforコマンドで読めないパスになるため move %TableList% "%SaveDir%%TableListDst%" popd endlocal exit /b :-------------------------------------------------------------------------------- : テーブルをバックアップする。 :-------------------------------------------------------------------------------- :ExportTable setlocal set server=%~1 set db=%2 set table=%3 set saveDir=%~4 set filePath=%saveDir%%table%.txt bcp %db%.dbo.[%table%] out "%filePath%" -S%server% -T -c > nul endlocal exit /b
動作
対象のサーバーの対象のデータベースの各テーブルをBCPでエクスポートする。
実行日時のフォルダに格納されるのでその時点のデータベースをスナップショットできます。
BCPでエクスポートしているので、テキスト差分などでデータの相違を比較することも簡単になりました。
インポートするバッチ
ソースコード
CleanImport.bat
@echo off setlocal :-------------------------------------------------------------------------------- : 概要:ExportAllTables.batによりエクスポートされたフォルダから : 対象のデータベースにクリーンインポートする : 引数: : %1-対象のサーバー : %2-対象のデータベース名 : 特記事項:サーバーへのアクセスは信頼関係接続で行う。 :-------------------------------------------------------------------------------- :-------------------------------------------------------------------------------- : 変数 :-------------------------------------------------------------------------------- : DB設定 set Server=%~1 set DB=%~2 set tablesDir=%~3 : 引数チェック if "%Server%"=="" ( echo exit /b 1 ) if "%DB%"=="" ( exit /b 2 ) if not exist %tablesDir% ( exit /b 3 ) : 対象DBのテーブル一覧 set TableList=TableList.txt :-------------------------------------------------------------------------------- : メイン処理 :-------------------------------------------------------------------------------- set baseDir=%~dp0 pushd %tablesDir% if not exist %TableList% ( exit /b 4 ) : 出力したテーブルのリストから1行ずつクリーンインポートする。 pushd %tablesDir% for /f "delims=" %%i in (%TableList%) do ( call :CleanImportTable "%Server%" %DB% %%i ) popd endlocal exit /b 0 :CleanImportTable setlocal set server=%~1 set db=%~2 set table=%3 sqlcmd -S (local) -Q "truncate table %db%.dbo.[%table%]" bcp %db%.dbo.%table% in %table%.txt -T -S%server% -c endlocal exit /b pause
動作
指定のサーバーとデータベースに対して指定のフォルダの中のエクスポート済データをインポートする。
前述のエクスポートしたデータベースの状態にします。
TruncateしてBCPでインポートするだけ。割とテストとバグ再現などで活躍してます。
感想
BCP最高~
PowershellからVBScriptの連係
社内でエクセルファイルを取り扱う時VBScriptが実装楽で早い(Excelオブジェクトの開放など)時が多く、
それ以外についてはPowershellが実装が楽です。
連係を円滑に行うための流れを調べました。
連係のための関数・変数
Powershell
コマンドの実行
コマンドの実行は Invoke-Expression で行います。
参考URL: Windows PowerShell の機能
例
$cout = Invoke-Expression -Command "ping localghost"
コンソール出力が戻り値として取得できます(便利)
コマンドの終了コードの取得
Invoke-Expressionで実行したコマンドの結果は $lastExitCode で行います。
VBScript
コンソール出力
コンソール出力は WScript.Echo で行います。
参考URL: Echo メソッド
終了コードの設定
終了コードの設定は WScript.Quit で行います。
参考URL:Quit メソッド
連係例
$foo = Invoke-Expression -Command 'cscript //nologo "C:\ReadExcel.vbs" "Bar.xls"' if($lastExitCode -eq 0) { echo "成功しました。`n結果" + $foo } else { echo "失敗しました。" }
VBScript実装
WScript.Echo "コンソールに呼び元が欲しい情報を出力する。" ' 終了コード If isError Then WScript.Exit 1 Else WScript.Exit 0 End If
以上!
C# Zipまるごと解凍の上書き対応(ExtractToDirectory)
概要
Zipを対象のディレクトリにまるごと解凍する場合 ZipFileExtensions.ExtractToDirectory を使いますが、
このメソッド、上書き対応してないんです。
なので、上書き対応したメソッドを定義しました。
拡張クラスで追加したのは以下メソッド
ZipArchiveEntry.IsDirectory
解凍するエントリーがフォルダかどうか判定するメソッド。
ZipArchive.ExtractToDirectory
上書きフラグを指定して、対象のディレクトリにまるごと解凍するメソッド。
ソースコード
既存の拡張クラスと領域が同じ場合、
拡張クラス名をどうつければいいか判断つかなくなりますね。
ということでとりあえず「My◯◯」形式で命名・・・。(「◯◯Ex」形式の方がいいかな?)
/// <summary> /// ZIP拡張クラス。 /// </summary> public static class MyZipFileExtensions { /// <summary> /// エントリーがディレクトリかどうか取得する。 /// </summary> /// <param name="entry">ZIPアーカイブエントリー</param> /// <returns></returns> public static bool IsDirectory(this ZipArchiveEntry entry) { return string.IsNullOrEmpty(entry.Name); } /// <summary> /// ZIPアーカイブ内のすべてのファイルを特定のフォルダに解凍する。 /// </summary> /// <param name="source">ZIPアーカイブ</param> /// <param name="destinationDirectoryName">解凍先ディレクトリ。</param> /// <param name="overwrite">上書きフラグ。ファイルの上書きを行う場合はtrue。</param> public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, bool overwrite) { foreach (var entry in source.Entries) { var fullPath = Path.Combine(destinationDirectoryName, entry.FullName); if (entry.IsDirectory()) { if (!Directory.Exists(fullPath)) { Directory.CreateDirectory(fullPath); } } else { if (overwrite){ entry.ExtractToFile(fullPath, true); } else { if (!File.Exists(fullPath)) { entry.ExtractToFile(fullPath, true); } } } } } }
以上!