2026年2月25日 星期三

【Google 試算表教學】一鍵自動化:製作「快速插入帶格式新列」的自定義按鈕

引言

在處理大量數據時,手動插入新列再重新調整格式(框線、底色、字體)總是讓人感到繁瑣。身為追求效率的工程師與數位創作者,我們需要更聰明的做法!今天將教大家如何利用 Google Apps Script,製作一個可以「智慧偵測選取範圍」並「自動帶入樣式」的自定義按鈕,讓你的試算表進化為自動化工具。


🚀 核心功能介紹

這套方案不僅能插入新列,最厲害的地方在於它會自動偵測你目前選取了幾列

  • 選取 1 列:按一下按鈕,下方新增 1 列相同樣式的空白列。

  • 選取 5 列:按一下按鈕,下方直接新增 5 列相同樣式的空白列。


第一步:撰寫自動化腳本 (Apps Script)

首先,我們要賦予試算表「智慧」。請在 Google 試算表中點選 「延伸功能」 > 「Apps Script」,並貼入以下程式碼:

JavaScript
/**
 * 功能:智慧插入新列並自動套用選取範圍的格式
 */
function insertRowsWithStyle() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var range = sheet.getActiveRange();
  
  var firstRow = range.getRow();
  var numRows = range.getNumRows(); // 自動取得選取的列數
  var lastColumn = sheet.getLastColumn();

  // 1. 在選取範圍的下方插入相同數量的列
  sheet.insertRowsAfter(firstRow + numRows - 1, numRows);

  // 2. 定義來源樣式範圍(你目前的樣板列)
  var sourceRange = sheet.getRange(firstRow, 1, numRows, lastColumn);
  
  // 3. 定義目標範圍(剛產生的空白列)
  var targetRange = sheet.getRange(firstRow + numRows, 1, numRows, lastColumn);

  // 4. 僅複製格式(確保新列乾淨但漂亮)
  sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_FORMAT);
  
  // 提示:若需要連公式一起複製,可取消下方代碼的註解
  // sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_FORMULA);
}

第二步:製作精美的 UI 自定義按鈕

腳本寫好了,現在我們需要一個「實體按鈕」來觸發它:

  1. 插入圖形:點選選單 「插入」 > 「繪圖」

  2. 設計按鈕:使用「圓角矩形」畫出一個按鈕,輸入文字如「新增樣版列」,並調整你喜歡的顏色。

  3. 放置按鈕:儲存後,將按鈕移動到標題列或凍結視窗區域,這樣無論怎麼捲動都找得到它。


第三步:將腳本「綁定」到按鈕

這是最關鍵的一步,讓按鈕與程式碼連動:

  1. 對著按鈕點擊 右鍵(或點擊右上角的三個點 )。

  2. 選擇 「指派指令碼」 (Assign script)

  3. 輸入函數名稱:insertRowsWithStyle (注意大小寫需一致,且不需括號)。

  4. 完成! 第一次執行時,請記得點選「允許授權」。


💡 專家進階小技巧

Q: 為什麼不直接用快捷鍵?

A: 雖然 Ctrl + Alt + Shift + = 可以插入列,但它無法精準地控制「僅貼上格式」或「跨工作表套用特定樣版」。透過自定義按鈕,你可以將這套邏輯封裝,甚至分享給協作同事使用,大大降低出錯率。


結語

透過簡單的幾行腳本,我們就能把機械式的操作變成一鍵完成。如果你在公司負責維護複雜的報表,這個小工具絕對會讓你成為辦公室裡的試算表專家!


覺得這篇文章實用嗎?

歡迎將此網址分享給你的同事,或是留言告訴我,你還希望實現哪些自動化功能!

2025年3月31日 星期一

BigQuery 筆記1 – 如何使用 bq 指令工具設定資料集(表)的到期時間


筆記:如何使用 Google Cloud BiqQuery 的指令用法

一、 設定資料集的效期

語法:
bq update --default_table_expiration ttl_seconds project_id:dataset

說明:
  • ttl_seconds 最小可用值為 3600 秒 (即最短效期為1小時, 參閱範例 1)若要取消資料集預設效期僅需將 ttl_seconds 設定為0 即可 (範例 2)
  • default table expiration 設定僅適用於新建立的資料表,已存在的資料表會保持原設定狀態。若要修改已存資料表效期,請參閱"二、設定資料表的效期"


範例 1: set expiration 1 hours later to myDataset

    bq update --default_table_expiration 3600 myProject:myDataset

範例 2: disable expiration to myDataset

    bq update --default_table_expiration 0 myProject:myDataset

二、設定資料表的效期

語法:
    bq update --expiration=SECONS PROJECT:DATASET.TABLE

範例 3: set expiration 2 hours later to myTable

    bq update --expiration 7200 myProject:myDataset.myTable

範例 4: disable expiration to myTable

    bq update --expiration 0 myProject:myDataset.myTable


參考資料

2022年12月31日 星期六

Typescript beginning with ts-node

Install nvm first


curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

Example of install nvm

~$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 15916  100 15916    0     0  32283      0 --:--:-- --:--:-- --:--:-- 32283
=> Downloading nvm from git to '/home/ci/.nvm'
=> Cloning into '/home/ci/.nvm'...
remote: Enumerating objects: 358, done.
remote: Counting objects: 100% (358/358), done.
remote: Compressing objects: 100% (304/304), done.
remote: Total 358 (delta 41), reused 164 (delta 28), pack-reused 0
Receiving objects: 100% (358/358), 218.72 KiB | 1.40 MiB/s, done.
Resolving deltas: 100% (41/41), done.
* (HEAD detached at FETCH_HEAD)
  master
=> Compressing and cleaning up git repository

=> Appending nvm source string to /home/ci/.bashrc
=> Appending bash_completion source string to /home/ci/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

Install and select Node.js version by nvm command line

nvm install v18

Please logout and login again to activate nvm.sh shell environment

~$ nvm ls
            N/A
iojs -> N/A (default)
node -> stable (-> N/A) (default)
unstable -> N/A (default)
~$ nvm install v18
Downloading and installing node v18.12.1...
Downloading https://nodejs.org/dist/v18.12.1/node-v18.12.1-linux-x64.tar.xz...
################################################################################################################################ 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v18.12.1 (npm v8.19.2)
Creating default alias: default -> v18 (-> v18.12.1)
~$ nvm ls
->     v18.12.1
default -> v18 (-> v18.12.1)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v18.12.1) (default)
stable -> 18.12 (-> v18.12.1) (default)
lts/* -> lts/hydrogen (-> v18.12.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.21.2 (-> N/A)
lts/gallium -> v16.19.0 (-> N/A)
lts/hydrogen -> v18.1

Install typescript


~$ npm install -g typescript

added 1 package, and audited 2 packages in 2s

found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 8.19.2 -> 9.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.2.0
npm notice Run npm install -g npm@9.2.0 to update!
npm notice

install typescript with specific version

npm install -g typescript@4.6.4

Example of hello.ts


Create example hello.ts file

cat << EOF >> hello.ts
var name:string = "Coder of Typescript";
console.log(`Hello, ${name}`);
EOF

Results of hello.ts

~$ ts-node hello.ts
Hello, Coder

Conclusions

I considere that typescript is a good tool for nodejs to write more stable code. Enjoy The journal for Typescript writing!



2021年7月28日 星期三

ffmpeg 降低聲音品質來縮小 mp3 檔案大小

 

目的縮小MP3檔案大小
  • 雙聲道改單聲道

  • 範例為音訊位元速率(bitrate) 從 160 kb/s 降為 64 kb/s

指令語法

ffmpeg -i <160k stereo filename>.mp3 -ac 1 -b:a 64k <output 64k mono filename>.mp3

-ac <channels> 設定音訊頻道數(set number of audio channels)

  • 1 表示單聲道(mono)

  • 2 表示雙聲道(stereo)

-b:a <bitrate> 音訊位元速率(bitrate)

小結

檔案大小縮小約為原來的 39.88%

~$ python
Python 3.9.6 (default, Jun 29 202104:45:03)
..
>>> round(80973 / 203040 * 100,2)
39.88

執行指令範例

$ ffmpeg -i 1_setup_160k_stereo.mp3 -ac 1 -b:a 64k 1_setup_64k_mono.mp3
...
$ ffmpeg -i 1_setup_160k_stereo.mp3
Input #0, mp3, from '1_setup_160k_stereo.mp3':
Duration: 00:00:10.12, start0.069063, bitrate: 160 kb/s
  Stream #0:0: Audio: mp3, 16000 Hz, stereo, fltp, 160 kb/s
  Metadata:
    encoder         : LAME3.98r

$ ffmpeg -i 1_setup_64k_mono.mp3
Input #0, mp3, from 1_setup_64k_mono.mp3':
Metadata:
  encoder         : Lavf58.45.100
Duration: 00:00:10.08, start0.069063, bitrate: 64 kb/s
  Stream #0:0: Audio: mp3, 16000 Hz, mono, fltp, 64 kb/s


$ ls -la 1_setup*
-rw-r--r--1 tester staff  203040 Jul 24 18:38 1_setup_160k_stereo.mp3
-rw-r--r--1 tester staff   80973 Jul 24 18:43 1_setup_64k_mono.mp3

Dev Tips - command line snippets

 

Command - equal to ldd

objdump -p <path/to/program> | grep -i needed

Command - while loop with date and sleep

while [ 1 ] ; do date +"%M:%S" ; sleep 1 ; done

Command - cp

merge one folder to another folder

if file exists in dummy_tmp, it will replace by file in origin_tmp

$ cp -RT origin_tmp/ dummy_tmp/
$ diff -ur dummy_tmp origin_tmp

2021年7月14日 星期三

Bash Tip - date 日期指令轉換 unix epoch time 範例

 

Command - date

Example 1 date - convert unix epoch timestamp to date string

$ date  --date='@1617694020'
Tue 06 Apr 2021 07:27:00 AM UTC

Example 2 date - convert unix timestamp to custom formatted date string


$ date +"%Y-%m-%d %H:%m" --date='@1617694020'
2021-04-06 07:04
$ date  --date='@1617694020.904'
Tue 06 Apr 2021 07:27:00 AM UTC

Example 3 date -- MacOS Mojave convert timestamp to date string


## MacOS Mojave not support --date
$ date  --date='@1617694020.904'
date: illegal option -- -
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
          [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
## use -r to instead
$ date -r 1625043610 +"%Y%m%d %H:%M:%S"
20210630 17:00:10

2021年1月21日 星期四

bash tips - 使用部分執行檔名來發出終止程式指令 terminate processes by partial process name

在 Linux 系統中,時常會遇到需要終止執行中的程式,如果只有單一執行檔程式執行多個 Instances 時,可簡單使用下列指令例如:

killall <process name>

但若是有多個 prefix 相同的程式就要分別指定

killall test_a test_b test_c

為了方便使用,初步寫一版可使用部分執行檔來終止程式的腳本,下例腳本是使用以下 /bin/sh 測試:

  • busybox v1.31
  • dash 0.5.8-2.10

Script example


#!/bin/sh
pname="$1"
if [ "x$pname" = x ]; then
echo "syntax: <partial process name>"; exit 1 ; fi
ps -a | grep "$pname" | \
grep -v grep | \
sed -e "s/^[ ]*\([0-9][0-9]*\) .*$/\1/g" | \
while read pid ; do kill $pid ; echo "terminate $pid" ; done

 Test output

~$ sleep 86400 &
[1] 2824
~$ sleep 86402 &
[2] 2832
sh 加上 -x 可除錯執行


~$ sh -x terminate_pname.sh sleep
+ pname=sleep
+ [ xsleep = x ]
+ ps -a
+ grep sleep
+ grep -v grep
+ sed -e s/^[ ]*\([0-9][0-9]*\) .*$/\1/g
+ read pid
+ kill 2824
+ echo terminate 2824
terminate 2824
+ read pid
+ kill 2832
+ echo terminate 2832
terminate 2832
+ read pid
[1]- Terminated              sleep 86400
[2]+ Terminated              sleep 86402

參考文章