サポンテ 勉強ノート

サポンテの勉強ノート・読書メモなどを晒します。

「自然の家計」とは

 農業講座を読んでいると「自然の家」または「自然の家計」という言葉が出てきます。自分にはまったくなじみの無い言葉であったため、さっぱり理解できませんでした。調べた限りのことを書いておきますね。

該当書籍

 該当の書籍はこちら。「自然の家」という言葉が48ページに登場します。

 または別の翻訳で、以下では「自然の家計」となっています。

原書に記載の単語

 「自然の家計」「ドイツ語」「慣用句」などのキーワードで検索したのですが、サッパリ見つかりませんでした。ですが後者の本には括弧書きで「ネイチャーズ・ハウスホールド」とありました。どうやらこちらはドイツ語から直接翻訳したものではなく、ドイツ語から英語に翻訳したものを下敷きに邦訳したものらしいことがわかります。

 というか、シュタイナーの書籍(GA)は全部 PDF で公開されている?

 ありがたく「Nature's household」で検索してみると、Gemini 含めていろいろ出てきます。これをドイツ語に翻訳し「Naturhaushalt」で検索してみると、Wikipedia の記事が見つかりました。

Naturhaushalt - Wikipedia(独)

言葉の意味

 Wikipedia や Gemini の解説をかいつまんで書いてみると以下のようになります。

 エルンスト・ヘッケルは、自然界の相互作用を「既存の資源から利益を得ようとする動植物の競合」であり、それを経済になぞらえて「支出と利益の均衡」と捉えました。それまでになかったこうした視点をヘッケル自身は「オイコロジー」と名付け、このことからヘッケルは現代生態学エコロジー創始者であると言われています。「自然の家計」は、ヘッケルが手紙の中でオイコロジーという新しい学問を説明するために使用した詩的な表現です。

 つまり「自然界のバランスがとれた状態」または現代生態学すなわち「エコロジー」と同義であると解釈してよいかと思われます。

ブックマークレットを作成する際の注意点

はじめに

 最近またブックマークレットを作る機会があったのですが、ちょっと注意した方がいいかもと思ったことがあったので書き出してみます。

ユニオンクリエイティブ ももこイラスト『縁ちゃん〈着物〉』 ノンスケール PVC&ABS製 塗装済み 完成品フィギュア

サイドエフェクト

 ブックマークレットは、サイトの構造を直接あるいは間接的に操作します。それはサイト開発者の意図や責任の範囲外です。近年のウェブサイトはどんどん複雑になっており、それはすでに開発者の手に負えるものではなくなってきています。そのようなサイトの構造を操作することによって、何らかの副作用サイドエフェクト、それも不都合な副作用が起きないとも限りません。

 起きるかもしれないし、起きないかもしれない。

 ブックマークレットの開発者も、ユーザーもそれを認識しておくべきでしょう。

突然動かなくなる可能性

 上記と若干関連しますが、とくに頻繁に更新やメンテナンスが行われている活発な Web サービスは、更新によってサイトの構造が変わり、ブックマークレットが動かなくなってしまう事が起こりえます。

 最近作成したブックマークレットは、業務で使用している GitHub Enterprise に向けたものでした。作成する際に、一般向けサービスの GitHub 無印を参考にしようと考えました。しかし、同じような見た目でも中身の構造がまったく異なっていました。これはサービスによって更新頻度が異なることが一因と考えられます。今後、この構造が統一の方向に向かうのか、あるいはまったく違う進化を辿るのかは予測できません。

 サービスの更新に合わせて、そのサービスに特化したブックマークレットは突然動かなくなる可能性があることも、気をつけたいです。

すべてのサイトで有効になってしまう

 ブックマークレットは表示中のウェブサイトなら、すべてが対象です。特定のサイトのために作ったブックマークレットでも、ブックマークバーに並んでいたらうっかり関係ないサイトでクリックしてしまうかもしれない。

 これも「サイドエフェクト」と言えるかもしれませんが、そのとき何が起きるのか予測できません。

 ブックマークレットにサイトの判定を入れれば良いのですが、そもそもブックマークレットは短く書きたいという宿命があります。文字数ギリギリで判定を入れる余地がない場合もあり得ます。

// ブックマークレットで最初にサイトを判定する例
javascript:!function(){
    // ホスト判定
    if (location.host != 'github.com') { return; }
    
    /* ... やりたい処理 ... */
    
}();

サーバに負荷をかける可能性

 最近の Web サービスはリアクティブです。つまり、ユーザの操作によって、必要なデータだけを部分的にロードし、ネットワークリソースに余分な負荷をかけないようにしています。

 ブックマークレットを実行することで、サーバに想定外の負荷をかける可能性があります。それはもちろんリソースを消費しますし、場合によっては利用者に料金が請求される可能性もあります。十分に注意しましょう。まあこれは、コンピュータの利用すべてに対して言えることですが。

 以前、業務で保守している社内データベースに一つの端末からの高負荷アクセスがあり、社内全体の業務が一時停止するということがありました。原因は Windows Power AutoMate を使った業務アプリの負荷試験でした。あろうことか本番で負荷試験をされてしまったのです。これはもちろんシステム担当者ではなく、自分自身の業務を自動化しようとするユーザによるものでした。

 プログラムやスクリプトを使って、様々なことを自動化するのはコストやリソースを削減するための手段です。そこを履き違えないようにしましょう。ブックマークレットでももちろん繰り返し処理などを作ることが出来ます。サーバに思わぬ負荷をかけないように注意したいものです。

GitHub Enterprise の【Load more...】ボタンを自動的にクリックするブックマークレット

はじめに

 サポンテはプルリクした後の指摘が多いのと、また自身も細かくコミットを積み上げる性質なので、プルリクコメントのリストが簡単に長くなりがちです。そしてサポンテだけかと思っていたら、チーム内のほとんどの人が同様の悩みを持っていることが判りました。

 以下のような機能拡張があることを教えていただいたのですが、残念ながら上手く動作しませんでした。

GithubのLoad moreボタンを自動で押してくれるChrome拡張作った - なんかのLog

 ソースを確認したところ、先頭で host 名確認をしているため GitHub 無印では動作するものの、Enterprise では動かないことが判りました。また他にも理由がありそうでした。

 サポンテはブックマークレットが好きなので、ブックマークレットで実行したい。作ってみました。

お隣の天使様にいつの間にか駄目人間にされていた件 フィギュア -椎名真昼-

ブックマークレット(※ 動作未確認)

 GitHub Enterprise では host 名に企業名が入っていたりするので、ブックマークレット先頭の YourCompanyName を適切な名前に変更してお使いください。

javascript:!function(){if(location.host=="github.YourCompanyName.com"){var b=()=>{let a=Array.from(document.querySelectorAll('[data-disable-with\x3d"Loading…"]'));if(a.length<=0)return!1;a[0].click();return!0};b();var c=setInterval(()=>{b()||clearInterval(c)},2E3)}}();

ソースコード

 圧縮前のソースコードです。今回は Js Compressor を使って圧縮しました。

javascript:!function() {
    // 組織判定
    const co = 'YourCompanyName';
    // "Load more..." を探す周期(ミリ秒)
    const interval = 2000;
    
    // Git Hub Enterprise 以外なら処理を実行しない
    if (location.host != 'github.' + co + '.com') { return; }
    
    const clickLoadMore = () => {
        // "Load more..." を探す
        let loadMores = Array.from(document.querySelectorAll('[data-disable-with\x3d"Loading…"]'));

        // 無かったら処理を終える
        if (loadMores.length <= 0) { return false; }

        // (有った)
        // "Load more..." をクリックする
        loadMores[0].click();
        return true;
    }

    clickLoadMore();

    const intervalId = setInterval(() => {
        // "Load more..." を探してクリックする
        const clicked = clickLoadMore();

        // 無かったら処理を終える
        if (!clicked) {
            // 周期処理を止める
            clearInterval(intervalId);
            return;
        }
    }, interval);
}();

ブックマークレットとは

 ブラウザのアドレス欄には http: とか https: とか ftp: とか、「プロトコル名」 + コロンで始まるものを書くことが出来ますが、javascript: で始まる短いコードを書くことも出来ます。これを「じゃあ、そのコードを『ブックマーク』に登録しておけば、どのページを開いていても横断的に使えるのでは?」というアイディアをブラウザに実装したものがブックマークレットです。1998 年が元年なので、ずいぶん歴史があります。ネットで探すとたくさんのブックマークレットが見つかります。

 サーブレットアプレット、コマンドレットなどの用語を知っている方は「ブックマークレット」という言葉を聞いただけで「ああ、なるほど。そういう方法もあるのか」とピンと来るかもしれません。

【Numbers】時間を小数点時間に変換

はじめに

 昨日、PowerShell で勤務時間の計算をするスクリプトを投稿しましたが、Numbers を使っている方もいるだろうと思います。

 軽く調べたところ、Excel のようには簡単に情報が出てこなかったので、そちらの紹介をします。サポンテが考えた範囲なので、もっと良い方法があるかもしれません。

結果

 以下のようなイメージです。列「開始」「終了」が直接入力、「時間」と「時間(小数表記)」が数式です。

ゴールデンヘッド - ブルーアーカイブ - アロナ 1/7 PVCフィギュア 限定 亜美 あみバージョン

続きを読む

勤務時間を計算する【macOS/PowerShell/Windows】

はじめに

 職場によるかも知れませんが、タスクにかかった時間ごとに業務報告が必要です。どのタスクにどれだけの時間を費やしたのかを報告するものです。

 時間の計算って面倒じゃないですか?まあ表計算ソフトを使えば簡単なのですが、そのために表計算ソフトを起動して、記入して計算して、閉じて「保存しない」ボタンを押す、と、結構手数が多い。しかも報告を、45分なら 00:45 ではなく 0.75h として報告しなきゃいけない場合とか。

 サポンテは常時起動しているプレーンテキストファイルに日誌を書いています。以下のようなものです。

## 2025/09/29(月)
晴れ。
09:00-09:10 全社朝礼
09:10-10:00 メールチェック
10:00-12:00 ドキュメントの修正作業
12:45-18:00 新規機能の開発
15:00-16:00 営業ミーティング
...

 などなど。なので、ここから時間範囲文字列をコピペして計算したい。

[YAYANA]初音ミク 着物 フィギュア コレクションドール 置物 台座あり 装飾品 可愛い 軽量 萌えグッズ 可愛い 誕生日プレゼント 車飾り 人気 おもちゃ 卓上置物

使用イメージ

 常に開いているターミナルで、「コマンド名」+「時刻文字列」を入力し、結果を表示します。

> tc 01:00-01:15

出力結果イメージ

-----
差: 00:15
小数表記: 0.25h
残りまたは残業: 7.75h
-----

スクリプト

 Windows でも macOS でも使えるように PowerShell で作成しました。スクリプトファイルを PATH の通っているところに置いてください。macOS お使いの方は実行権限を付与しておいてください。Windows をお使いの方は、拡張子なしで実行したい場合 cmd ファイルを作成しておいてください。

 スクリプト名(あるいは cmd 名)は任意です。サポンテは tc (Time Calculation)としました。

#!/usr/local/bin/pwsh

param (
    [string]$inputRange
)

# 入力例: "01:00-01:15"
if (-not $inputRange) {
    Write-Error "時間範囲を引数として渡してください。例:'01:00-01:15'"
    exit
}

# 区切り文字で分割
$pattern = '[^0-9:]{1,}'
$times = $inputRange -split $pattern
if ($times.Length -ne 2) {
    Write-Error "正しい形式で入力してください。例:'01:00-01:15'"
    exit
}

# 時刻を TimeSpan に変換
try {
    $startTime = [TimeSpan]::Parse($times[0])
    $endTime = [TimeSpan]::Parse($times[1])
} catch {
    Write-Error "時刻の解析に失敗しました。正しい形式で入力してください。例:'01:00-01:15'"
    exit
}

# 差を計算する
$duration = $endTime - $startTime

# 差の絶対値を計算する
if ($duration.TotalSeconds -lt 0) {
    $duration = -$duration
}

# 昼休憩を計算
$lunchStart = [TimeSpan]::Parse("12:00")
$lunchEnd = [TimeSpan]::Parse("12:45")
if ($startTime -lt $lunchStart -And
    $lunchEnd  -lt $endTime) {
    $duration = $duration - [TimeSpan]::Parse("00:45")
}

# その他休憩を計算
$break1Start = [TimeSpan]::Parse("10:00")
$break1End = [TimeSpan]::Parse("10:15")
if ($startTime -lt $break1Start -And
    $break1End  -lt $endTime) {
    $duration = $duration - [TimeSpan]::Parse("00:15")
} # 他にも休憩があるなら、同様に計算

# 時間と小数表記を計算する
$diffMinutes = $duration.TotalMinutes
$diffHourDecimal = [math]::Round($diffMinutes / 60, 4)

# 残り時間または残業時間を計算する
$remainingTime = 8.0 - $diffHourDecimal
if ($remainingTime -lt 0) {
    $remainingTime = [math]::Abs($remainingTime + 0.25)
}

# 出力する
Write-Output("-----")
Write-Output("差: {0:hh\:mm}" -f $duration)
Write-Output("小数表記: {0}h" -f $diffHourDecimal)
Write-Output("残りまたは残業: {0}h" -f $remainingTime)
Write-Output("-----")

おわりに

 Excel をずっと開いているという人や、上記のような日誌を Excel で書いているという人はあまり困っていないかも知れませんね。誰しも一日中つねに起動しているツールがあるかと思いますが(メールソフトやチャットソフトなど)サポンテの場合は Visual Studio Code だったので、統合ターミナルからすぐに使えるものが欲しかったのでした。

 上記スクリプトはほとんど AI に作成してもらいました。AI は、ミニツールを作る分にはそこそこ便利ですね。

Excel ワークシートの内容を保存する記事を修正しました

はじめに

 職場が変わり、OS が変わり、以前作ったミニツールが動かなくなっていました。

 おもに PowerShell の変更によるものと思われます。下記の記事に追記をしました。

ワークシート上の図を画像ファイルとして保存【Excel/VBA/Windows】 - サポンテ 勉強ノート

ワークシート上のセル選択範囲を画像ファイルとして保存【Excel/VBA/Windows】 - サポンテ 勉強ノート

修正したスクリプトの一部

Private Sub SaveClipboardImage()
    Dim objWSH As Object
    Dim cmd As String

    ' 保存パスが未入力なら処理をしない
    If ActiveSheet.Range("A1").Value = "" Then Exit Sub

    Set objWSH = CreateObject("WScript.Shell")

    cmd = "powershell.exe -Command Add-Type -AssemblyName System.Windows.Forms; " & _
        "[System.Windows.Forms.Clipboard]::GetImage().Save(\""" & _
        ActiveSheet.Range("A1").Value & "\"", [System.Drawing.Imaging.ImageFormat]::Png)"

    objWSH.Run cmd, 1, True
End Sub

Excel VBA 高速化のスニペット

はじめに

 Excel VBA の高速化テクニックは定番のスニペットがいくつかあり、サポンテが態々わざわざ書くほどの余地はないと思っていました。ですが「Excel VBA 高速化」などで検索して上位に表示されるものに満足できなかったので、こちらにサポンテのスニペットを載せておきます。

他と違うところ

 検索上位で見かける処理の高速化テクニックは、たとえばフラグを False にして、時間がかかる処理が終わったら True に戻す、というものです。以下の点を考慮したものが少ないなと感じました。

  • エラーハンドリングしておらず、処理中にエラーが発生したときフラグが戻らない
  • そもそも処理開始時点でのフラグの状態を確認せず、強制的に True にしている

 サポンテは関数( Sub でも Function でも)組み合わせたり使い回したりするので、後者の場合特に問題になります。

スニペット

Sub Test()
    Dim applicationScreenUpdating As Boolean
    Dim applicationEnableEvents As Boolean
    Dim applicationCalculation As Long
    Dim applicationCursor As Long
    
    On Error Goto RevertFlags
    
    With Application
        applicationScreenUpdating = .ScreenUpdating
        applicationEnableEvents = .EnableEvents
        applicationCalculation = .Calclation
        applicationCursor = .Cursor
        .ScreenUpdating = False
        .EnableEvents = False
        .Calclation = xlCalculationManual
        .Cursor = xlWait
    End With
    
    ' ここに重たい処理
    
RevertFlags:
    With Application
        .ScreenUpdating = applicationScreenUpdating
        .EnableEvents = applicationEnableEvents
        .Calclation = applicationCalculation
        .Cursor = applicationCursor
    End With
End Sub

ちなみに

 サポンテは、処理中に一時的に作業場所として新しいワークブックを作ったりするので、画面が無駄にチカチカしないよう、高速化以外の目的にも Application.ScreenUpdating を操作したりします。