昨年(2019)夏ごろから,検索サイトで「表計算,令和」で検索すると,筆者が書いた関連の記事が,よくトップに出てくる。別に紹介しまくる SNS アカウントもなければ,特に対策なんかもしていないのに,なぜ? ひょっとして,みんな「表計算ソフト」を使いこなしたいとは思いつつ,どうすればいいか分からず,さまよい辿り着くのだろうか。
そんなある日,市役所でもらったゴミ回収カレンダーの期限が切れてしまった。市のサイトからダウンロードした PDF で見ようとしたら,超重い。しかも,軽く見れそうな「テキスト版」も見つからなかった。でも,ゴミ回収の「毎月第○×曜日は……する」という「規則性」は,うまく表計算の表に埋め込めば,予定表くらい自動作成可能では? それならテキスト版の自作も簡単だ。で,実際に試したのが,以下の図。
▼ 表計算で自動的にゴミ回収日を表示させる |
「ハンドルをドラッグする」ということは,つまり B2 セルの内容を「下に向かってコピーしているだけ」で,下のセルには全て「同じ式」が設定されることになる。でも,同じ内容が表示されるわけではなく,曜日を反映した回収ゴミがキチンと表示される。表計算では,こうした仕組みを作ることができる。
役所,学校,介護施設や福祉作業所など,何らかの組織や団体には,このような「毎月第○×曜日に……する」的イベントはよくあるはず。この記事では,表計算ソフトにそうした予定表を自動生成させて作業を簡素化する方法と,ついでに「多言語化(m17n)」への対応方法など,超便利な使い方について述べてみたい。
● 経緯と概要
筆者のサイトでここ最近の一番の人気は,以下の記事。
「最近」と言っても,じつは昨年(2019)の夏頃から,検索サイトで「表計算,令和」で検索すると,ほぼトップあたりをウロチョロ。とはいえ,筆者はどこの SNS アカウントも持っていないから,そうした場で紹介などできないし,ましてや……「SEO」ってンですか? よく知らないレベルでっせ。そりゃ,一銭にもならんて。
それでも人気ということはどういうことか……ひょっとして,みんな「表計算ソフト」を使いこなしたいとは思っているものの,どうしたらうまく使えるか分からず,その「具体案」に飢えているのだろうかと。
一方,ある朝,「今日は何のゴミ回収の日かな」と思って,市のゴミ回収カレンダーの PDF を見ようとしたら,表示がすごく遅い。手元のパソコン内にダウンロードしたファイルでそれ。では,たしか先月9月まで「テキスト版」のデータが市のサイトで見れたから,それなら直ぐ読めるはず……と思ったものの,今月分以降が見つからない。回収するゴミの確認をしようとする度,重い PDF の表示を待っていたのでは,朝から気分も重くなりそうだったので,何とか対策したいと考えた。
「対策」と言っても,考えられるのは……その「テキストデータ」を自前で作ることくらいだ。だからって,その PDF を見ながらパソコンに打ち直すのはたいへんだなぁと,当初は思っていたのだが……。
考えてみれば,ゴミ回収日など「規則性」があるだろうから,うまいこと自動的に作れるのでは? そこで思い当たったのが「表計算」だ。ゴミ回収日の規則性を反映した「式」をうまく作成して埋め込めれば,収集日の一覧など数ヶ月分くらいあっという間に作れるだろうと。
しかも,そうした「規則性」のある予定は,ゴミ回収以外にもいろいろな施設や組織にあるわけで,それで「予定表」を自動で作成することができたら,ひょっとするとその「表計算の応用に飢えている人たち」にも役立つかもしれない……。
というわけで,ここではそうした「規則性」のあるイベントを,カレンダーやスケジュール表の予定に自動で埋められるような表計算ソフトの使い方を紹介すると共に,ついでに,それをもう少し応用して実現できる,簡単な「多言語化(m17n)」についても説明してみたい。
● 共通する留意事項
以降の解説に共通する留意事項は,以下の通り。詳細は後述の各節を参照。
- エクセルでは関数の値の区切りをコンマに
- 「日付」は原則として年まで指定
- セルの式と書式指定に使う英数字は必ず半角
なおこの他,「シート名の指定方法」も,この記事の解説とエクセルで異なるが,「多言語対応」でのみ留意の必要があることなので,後述の該当章に記載した。
◆ エクセルでは関数の値の区切りをコンマに
ここでは,数式の関数に指定する値の区切りに「セミコロン(;)」を使っているが,これは筆者が使っている OpenOffice のものなので,エクセルで使う時はこれを「コンマ(,)」に置き換えて欲しい。
たとえば,例で使っている IF() という関数で,記事解説とエクセルでの使い方の違いは以下の通り。
IF( 条件; 真の値; 偽の値 )
IF( 条件, 真の値, 偽の値 )
◆ 「日付」は原則として年まで指定
ここで扱う「日付」は,原則として「年まで指定されたもの」であることが前提。なぜかというと,曜日を計算で特定する時は必ず年も必要になるため。だから,「表示は月日だけ(あるいは日だけ)にしたい」セルにも年から設定する必要がある。その場合は「セルの書式指定」によって,年を表示させない対応をする。たとえば,以下のように書式を指定する。
M 月 D 日
スケジュール表など「日だけでいい」場合でも,入力する時は必ず年から入力し,上記「書式指定」で D だけのセルの書式指定をして「日だけ」を表示させるようにする。
◆ セルの式と書式指定に使う英数字は必ず半角
以降,「セルに式を設定する」例が多くあるが,そこで使う関数名やセル名,括弧などの記号類は,全て半角英数を使う。ただし,式の中のクォーテーション(")で囲んだ部分は「ただの文字」として扱われるため,全角を含む任意の文字が書ける。また,前節で述べたセルの書式指定と,TEXT() 関数で書式を指定するアルファベットで,日付の数値や「×曜日」などの文字に置き換える部分も必ず半角を使う。全角だとやはり「ただの文字」として扱われ,そのまま表示されるので注意。
● 曜日を求める (WEEKDAY)
たとえば,A1 セルに入力されている日付(年月日)の数値の曜日を求める関数はこう。
=WEEKDAY( A1 )
WEEKDAY( 日付 ) という関数は,日曜日を1として,土曜日の7までの数字を求めるもの。そのため,当然これだと数字が表示されるだけ。曜日を「文字」で表示させたい場合はもうひと工夫必要だが,次節以降で詳しく述べる。
念のため言っておくと,前章で述べた通り,A1 には「年」から指定された日付の値が設定されていることが前提。表示される曜日の数値が期待しているものと異なる時は,その辺りを確認のこと。以降も同様。
◆ 日本語の曜日を自動的に表示 (MID,TEXT)
日本語で曜日の漢字を表示させたい時は,こうするといい。
=MID("日月火水木金土"; WEEKDAY( A1 ); 1)
MID( 文字列; 位置; 文字数 ) という関数は,文字列の中の指定した位置から文字数分だけの文字を取り出すもの。ここでは文字数が1であるため,曜日の文字が1文字だけ表示される。
前章で述べた通り,上記式内のセミコロン(;)は,筆者が使っている OpenOffice の区切りであるため,エクセルではこれをコンマ(,)に置き換えて使って欲しい。以降の説明も同様。
「×曜日」と表示させたい時はこう。
=MID("日月火水木金土"; WEEKDAY( A1 ); 1)& "曜日"
&というのは,その左右を「文字として連結する」ことを示す。
もし括弧で囲って表示させたい場合はこう。
="("&MID( "日月火水木金土"; WEEKDAY( A1 ); 1)&")"
じつは上記は以下のような書き方もできる。
=TEXT( A1; "AAA" )
=TEXT( A1; "AAAA" )
=TEXT( A1; "(AAA)" )
TEXT( 値; 書式 ) という関数は,値に書式を適用した文字列を求めるもの。"AAA" などが,日付の数値から曜日を表示する書式になる。
こちらのほうが簡単ではある。が,使用環境が日本語の時はいいとして,英語圏の設定がされたパソコン環境でも同じように機能するかどうかは分からない。少なくとも,他言語向けデータを使用環境を変えずに作ろうとしても,この TEXT() 関数ではむずかしいと思われる。片や,前述 MID() 関数や,後述する CHOOSE() 関数などなら,他言語に対応させたい時は表示させたい内容の部分を変更するだけ,という点で分かり易く,汎用性も高いわけだ。
◆ 英語での曜日を自動的に表示 (CHOOSE, English)
英語の場合は「一文字」じゃ済まないから,少々厄介。それでも略号のように「全て3文字」なら割と簡単。
=MID("SunMonTueWedThuFriSat"; WEEKDAY( A1 )*3-2; 3)
「3文字ずつ」だから3倍して,「最初が1」になるように2を引いて,「3文字ずつ」だから,文字数指定も3にすればいいワケ。
フルスペルで表示させたいとなると,曜日により文字数が異なるため上記の方法は使えないから,別の関数を使う必要がある。
=CHOOSE(WEEKDAY( A1 ); "Sun"; "Mon"; "Tues"; "Wednes"; "Thurs"; "Fri"; "Satur")& "day"
CHOOSE( 番号; 第1; 第2; …… ) という関数は,番号に該当する「第×」番めの値を求めるもの。ここでは,曜日のつづりの最後は全て
"day" であるため,そこは省略し,前の部分を日付から求めた後で付加している。
ちなみに,それぞれ TEXT() 関数を使った方法は,以下の通り。
=TEXT( A1; "DDD" )
または
=TEXT( A1; "NN" )
=TEXT( A1; "DDDD" )
または
=TEXT( A1; "NNN" )
やはり日本語環境以外で,あるいは英語以外の言語でインストールされたパソコンで,どのような結果になるかは分からない。TEXT() ではなく CHOOSE() を使えば,どんな言語にも対応できるであろうことは,容易に想像してもらえると思う。
◆ 予定表の曜日埋めは「オートフィル」で簡単に
もうお気づきの方もいると思うが……述べて来たことを応用すれば,先の「予定表」の曜日欄など簡単に埋めることができると。たとえば,A1 セルに1日の日付を「年から」入力しておき,書式設定は「M/DD」などとしておいて,年の表示は省略する。で,隣の B1 セルには前述の「日本語の場合」で説明した曜日を求める式を設定しておく。
2日以降の「日付」の欄は,まず1日のセル(A1)だけ選択した状態から,そのセルのハンドル(セルを囲んでいる太い枠の角にある四角いポッチ)を下に向かってドラッグすると,2,3,4……と連番で埋めることができる。もし連番にならない時は,[Ctrl] キーを押しながらドラッグするとたいてい連番になる。「オートフィル」と呼ばれる機能。
B1 セルの曜日も同様にドラッグ操作で下にコピーすればいい。このコピーは曜日を求める「式」のコピーになり,左隣のA列にある日付に該当する曜日が表示されるだろう。ちなみに,この A1 と B1 の2つを選択した状態でハンドルをドラッグしてもうまくいくことが多い。
▼ オートフィル |
表計算ソフトで予定表を作成しようとして,いちいち「来月の1日は何曜日だ?」と言って,ぶら下がっているカレンダーをめくりに行っていた人は,いろいろとご苦労様でした。
◆ 翌月以降もラクにする (DAYSINMONTH, IF)
さらにラクしようとするなら,A1 の下の A2 セルに“=A1+1”という式を設定し,A3 以下は A2 をオートフィルでコピーしておくといい。B列は,既に述べたのと同様に,隣のA列の日付から曜日を求めて表示する設定にしておく。すると A1 セルから下は必ず翌日,翌々日……の日付の数値が続き,曜日はその日付の「年月日」を反映するのだから,A2 より下の日付と曜日入れ作業が不要になる。つまり,別の月の表に作り直す時は,A1 セルに1日の「年月日」を設定すれば終了!……ということ。翌月以降のカレンダー作りも超簡単になるワケです。
ここで問題になるのは月末。日は最大 31 日まであるが,29 日以降は存在しない月もある。とりあえずは,放っておいても翌月一日以降が表示される……つまり,2/29~2/31 に相当するセルには,通常年なら
3/01~3/03 が,閏年には 2/29~3/02 が表示されるだけだ。
ただ,予定が決まらないためにそこを「空欄」にしておいて,「来月一日は何もないのね」と誤解されても困るし,だからと言って月が変わる度にいちいち削除したりまた設定をし直すのも少々煩わしい。
筆者が使用している OpenOffice の表計算では,「その月の日数」を求める関数がある。たとえば,A1 セルに入力されている日付のある月の日数を求める場合は,以下のようにする。エクセルについては後述。
=DAYSINMONTH( A1 )
DAYSINMONTH( 日付 ) という関数は,日付を含む月の日数を求める。
つまり,「表示させたい日がこの日数を上回っていたら表示しない」設定ができれば,月末に「翌月」の日付が表示されてしまうことを防ぐことができる。具体的には,たとえば A31 セルに「31 日」を表示させるかどうかの判断は,以下のような式を設定すればいい。
=IF(DAYSINMONTH( A1 )<31; ""; A1-1+31)
IF( 条件; 真の値; 偽の値 ) という関数は,条件が成り立った時は「真の値」が,成り立たなかった時は「偽の値」が求まるもの。この式は,その月の日数が 31 より小さい……つまり「31 日がない」時は ""
(空文字列)を表示し,それ以外の時は「A1(つまり1日)の 30 日後の日付(つまり同月 31 日)の数値」が表示されることになる。2月を考えれば A29 と A30 のセルにも上記と同様な式の設定が必要になる。その際,2箇所ある 31 という数字を,29 日は両方とも 29 に,30 日は両方 30 にする。
式の中の“-1”というのは,1日と 31 日の日数の差が,実際は「30
日」であるための調整。もちろん“+30”と書いても同じだが,「31 という数を変更すべき」と分かり易くするためそう書いてある。だから,A1 セルは「同月1日」である必要がある。もし,A1 が「1日でない」予定表を作りたい時は,式の中に2ヶ所ある A1 の代わりに,両方とも同じ月の「1日」に当たるセルを指定して欲しい。
同時に,日が空欄のセルは曜日のセル(B列)も空欄にする必要がある。隣(A列)の日が空欄の時,曜日も空欄にする式は,こんな感じ。
=IF(A31=""; ""; "("& MID("日月火水木金土"; WEEKDAY(A31); 1)&")")
同じ式を B29~B31 のセルに設定する。これはコピーでいけるはず。
★ エクセルにはない DAYSINMONTH() (EOMONTH)
なお,ザッと調べた限りでは,この DAYSINMONTH() という関数は,エクセルにはないらしい。代わりに,月末の日付の数値を求める関数である EOMONTH() を使って,以下のようにする必要がある。
=IF(DAY(EOMONTH( A1, 0 ))<31, "", A1-1+31)
EOMONTH( 日付, ○ヶ月後 ) という関数は,指定した日付から○ヶ月後の月の最終日の日付の数値を求める。ここでは「○ヶ月後」が0なので,その日付を含む月の最後の日の日付になる。何日か「ではなく」年まで含む「日付の数値」なので,日にちを求める DAY() 関数(詳細は後述)も必要になる。これも A29 と A30 のセルに同様な設定をする。
また,この EOMONTH() という関数は OpenOffice でも使えるため,上記式の区切り文字を ","→";" にすれば OpenOffice でも使える。
一方,曜日はエクセルでも前述とほぼ同じ式(";"→"," 置換必要)が使える。
● 月を求める (MONTH)
日本語では,日付の月は数字で書くのが普通。数値で求める関数なら既にあるので,それを使ってこうすれば済む。
=MONTH( A1 )
MONTH( 日付 ) は,その日付を含む月を 1~12 の数で求める関数。
ただ,英語圏の場合は「月名」で書くのが普通。この章では,月ごとに異なる表示が必要となる場合の対応について考えてみる。
◆ 日本語の月の名前を自動的に表示
日本のカレンダーでは,あまり月の名前(睦月,如月,弥生……)で書かれているものはないが,ひょっとすると月ごとの会合で「皐月会」などと記載したい気取った輩もいるかもしれないので,考えてみる。
「全て(漢字)2文字」なら MID() 関数で簡単に求められるところだったが,「水無月,神無月」の2つが3文字なのでそうもいかない。まぁ,こうするしかないと思われる。
=CHOOSE(MONTH( A1 ); "睦月"; "如月"; "弥生"; "卯月"; "皐月"; "水無月"; "文月"; "葉月"; "長月"; "神無月"; "霜月"; "師走")
◆ 英語で月の名前を自動的に表示 (English)
月の名の場合は,むしろ「3文字」に固定された略号が使える英語のほうが簡単。
=MID("JanFebMarAprMayJunJulAugSepOctNovDec"; MONTH( A1 )*3-2; 3)
フルスペルで表示させたいとなると,日本語同様こんな感じになる。
=CHOOSE(MONTH( A1 ); "January"; "February"; "March"; "April"; "May"; "June"; "July"; "August"; "September"; "October"; "November"; "December")
ちなみに,それぞれ TEXT() 関数を使った方法は,以下の通り。
=TEXT( A1; "MMM" )
=TEXT( A1; "MMMM" )
もちろん,これも日本語環境以外で,あるいは英語以外の言語でどのような結果になるかは分からない。TEXT() ではなく CHOOSE() を使えば,どんな言語にも対応できる。
● 年を求める (YEAR)
年の数値だけ使いたい時は,YEAR() 関数を使う。
=YEAR( A1 )
YEAR( 日付 ) というのは,指定日付の年を「西暦で」求める関数。年だけ求める意味としては,予定表の「表題」に年を入れたい場合や,「元号(令和)」で表示したい時に使える。元号で表示するなら,以下のようにする。
="令和 "&( YEAR( A1 )- 2018 )& " 年"
なお,過去の元号や略号(Rxx),「元」年と表示,「必ず2桁」などへの元号表示の対応は,冒頭でも紹介した以下の記事を参照。
◆ 干支を求める (MOD)
「干支」なんて年賀状の時にしか使わなくなってはいるが,仕事がら(占いとか?)年ごとの干支の一覧などが重要な人もいるかもしれないので,考えてみる。
といっても,干支は「全て一文字」なので,割と簡単。こうする。
=MID("子丑寅卯辰巳午未申酉戌亥"; MOD(YEAR( A1 )+8; 12)+1; 1)
MOD( 数値; 除数 ) という関数は,数値を除数で割り算して,「剰余(余り)」を求めるもの。たとえば 2020 年なら,8を足しているから
2028 の剰余が計算されるが,12 で割り切れるから結果は0(ゼロ)になる。そこに1が足されているため,文字列の1文字めの「子」が求まる。「12 で割った余り」の範囲は 0~11 だが,1が足されているために,結果は 1~12 文字めの1文字が繰り返し求められることになる。
なお,ここで A1 には「日」を含む日付の数値が入力されている前提のため YEAR() という関数が使われているが,もし A1 に「年のみ」の数値(たとえば 2020)が設定されている場合は,この関数を省略して“A1+8”と記載すればいいことになる。
◆ 十干を求める
あまり使う機会がないかもしれないが,もし十干を求めるならこう。
=MID("甲乙丙丁戊己庚辛壬癸"; MOD(YEAR( A1 )+6; 10)+1; 1)
なお,前述の「十二支」と同様,A1 には「日」を含む日付の数値が入力されているという前提だが,もし A1 に「年のみ」の数値が入力されているなら“A1+6”と記載する。
「十干十二支」を求めるなら,前述の干支と組み合わせる。
=MID("甲乙丙丁戊己庚辛壬癸"; MOD(YEAR( A1 )+6; 10)+1; 1)& MID("子丑寅卯辰巳午未申酉戌亥"; MOD(YEAR( A1 )+8; 12)+1; 1)
● 予定表の自動作成
筆者がこの記事を書こうと思ったきっかけは,まず,市のサイトからダウンロードした「ごみ回収カレンダー」の PDF が,広告などの図が多いためかかなり重たくて,「今日は何の回収かな?」と毎日見るのは少々苦痛に感じ,そこでテキスト版を見たいと思ったものの,市のサイトでは見れなかった(作成前だったか?)ので,自分で作ろうと考えたため。といって,その PDF を見ながら全ての回収日をテキストに書き起こすなんて面倒だし,ほとんど「毎週×曜日は可燃ゴミ」とか「毎月第○×曜日は不燃ゴミ」と決まっているわけだから,その法則を表計算ソフトに式で記述できればラクだろう……という考えから。
そこでこの章では,表計算の日付の値から,その「毎週×曜日」とか「毎月第○×曜日」を求め,該当日に予定を表示する方法を考えたい。
◆ 「毎週×曜日」を求める (OR)
これは簡単。既出の WEEKDAY() 関数を使えばいいだけ。たとえば,筆者の地域では,毎週木曜が「PET ボトル・包装プラゴミ」の回収日。以下の式は,A1 の日付が木曜日の時に「PET プラ」と表示される。
=IF(WEEKDAY( A1 )=5; "PET プラ"; "")
あとは「曜日」を入れたのと同じ要領で,たとえば A1 セルから下に向かって日付が設定されている時に,曜日の右隣のC列を「回収ゴミ」の表示列とするなら,C1 セルに上記式を設定して下にコピーすれば,毎週木曜日に「PET プラ」と表示される。この場合も「オートフィル」を使ってコピーすれば,木曜日を探して手作業で「PET プラ」とコピペするよりもずっと早いわけだ。
筆者の地域では,毎週火曜日と金曜日が「可燃ゴミ」の回収日。このように,週に複数回ある場合の対応は,以下のようにする。
=IF(OR(WEEKDAY( A1 )=3; WEEKDAY( A1 )=6); "可燃ゴミ"; "")
OR( 条件1; 条件2 …… ) という関数は,指定した条件のうちのどれか1つでも成立すれば,「OR() 関数も成立した」として扱う関数。WEEKDAY() で求めた数が,3=火曜日,6=金曜日のどちらかが成立した時に「可燃ゴミ」と表示されることになる。
ただ,WEEKDAY() という同じ計算を2回しているという点で,あまりスマートではない。3 も 6 も「3の倍数(3で割った余りが0)」であることを利用すると,以下のようにも書ける。
=IF(MOD(WEEKDAY( A1 ); 3)=0; "可燃ゴミ"; "")
「月曜と木曜だったらどーすンだよ?!」的なツッコミが聞こえてきそうだが,そんなにむずかしくない。月曜日=2,木曜日=5 であり,3で割るとどちらも余りが2なのだから,こうすればいい。
=IF(MOD(WEEKDAY( A1 ); 3)=2; "可燃ゴミ"; "")
◆ 「第○×曜日」を求める (INT, DAY, AND)
筆者の地域では第1水曜が「金属類」の回収日。この「第○×曜日」の指定は少々工夫が要る。「第1×曜日」なら「7日以前」という条件だけだから簡単なのだが,「第2,第3,……」となると,8~14 日,15~21 日……という範囲指定が必要で,それをそのまま式にすると,ちょっと複雑になる。そこでまず,日付から「第○×曜日」の○の数字を求める式を考える。それはこうなる。
=INT((DAY( A1 )+6)/7)
INT( 数値 ) という関数は数値の小数点以下を省略して整数にする。
また,DAY( 日付 ) という関数は日付の数値がその月の何日かを求める。その値に6を足すから「1日」が7になり,7で割ると1になる。あとは,13(=7+6)までは商の整数部分が1になるから,7日まで結果は「1」になり,8日以降,7日ごとに1ずつ増えるというわけ。
まぁ,ここでは A1 セルは「ついたち」であると仮定しているから,第1×曜日に決まっているばかりか,下に向かって1日ずつ増えていくから,A1~A7 が第1週,A8~A14 が第2週,……てことも確定なのだが,表計算で「セルに同じ式を設定できる」ということは,「コピーすれば済む」わけで,「オートフィル」などで対応できるから,いちいち範囲を指定した式を作らずに済む省力効果が絶大。特に,予定表が月をまたいだり,また都合で始まりが1日ではない予定表が必要な時など,この「第○×曜日」の行の位置もズレることになるが,その場合も計算で自動的に求まるわけだから,予定表を作成する時に,いちいち既成のカレンダーを確認する手間が省けて助かるはずだ。
では,「第1水曜日」という条件はどう表現するかというと,前述の曜日を求める関数 WEEDKAY() と組み合わせて,以下のようにする。
=IF(AND(INT((DAY( A1 )+6)/7)=1; WEEKDAY( A1 )=4); "金属類"; "")
AND( 条件1; 条件2 …… ) という関数は,指定した各条件が全て成立した時に,「AND() 関数も成立した」として扱う関数。逆にどれか1つでも成立しないと,全体としても成立したことにならない。この式では,「第1×曜日」であることと,「水曜日」であることの両条件が成立した時に「金属類」の文字が表示されて,逆にどちらかでも成立しない時……つまり「第1水曜日」以外の日は,IF() 関数の「偽の値」である ""(空文字列)の表示になる。
筆者の地域では,第2と第4水曜が「不燃ゴミ」の回収日。このように,月に複数回の条件を指定したい時は,簡単には「第○週」指定部分に,前述の OR() 関数を組み合わせて,以下のようにする。
=IF(AND(OR(INT((DAY( A1 )+6)/7)=2; INT((DAY( A1 )+6)/7)=4); WEEKDAY( A1 )=4); "不燃ゴミ"; "")
同じ計算の式を2回記述するのがスマートじゃない感じがするなら,以下のように「2で割った時の余りが0(偶数)」の条件に置き換えても同じ。こうすると OR() 関数は不要になる。
=IF(AND(MOD(INT((DAY( A1 )+6)/7); 2)=0; WEEKDAY( A1 )=4); "不燃ゴミ"; "")
「第1・3×曜日」の場合は“=0”の部分を“=1”にすればいい……かと言うと,ちょっと不都合がある。というのは,月に数日ある「第5×曜日」も条件が成立してしまうため。実際にその日も回収があるならいいが,「第1・3×曜日だけ」の場合は,前述の OR() 関数で対応したほうが分かり易いだろう。
◆ 隔週 (WEEKNUM)
筆者の地域では,月曜日に「缶」と「ビン」の回収が交互にある。いわば「隔週」だ。
前節で「第2・4水曜日」の指定について考えた。これもほぼ2週間ごとだが,どの曜日も2~3ヶ月に一度程度「第5週」があるため,そこで3週間ほどあくことになり,そのまま「隔週」には応用できない。
一方,じつは「年始から何週目か」という「週の通し番号」を求める関数がある。それがこれ。
=WEEKNUM( A1; 1 )
WEEKNUM( 日付; 週初日 ) という関数は,OpenOffice では,週初日の番号を週始めとした時……つまり「1なら日曜日」を,「2なら月曜日」を週始めとした時,指定した日付がその年の第何週目に当たるかを求める。ここでは「週初日」が何曜日かはあまり重要ではない。重要なのは,月をまたいでも正確に7日ずつ区切った週の数が求められるという点。だから,この数値が偶数,または奇数になるのは,必ず「2週間ごと」になり,前の月に「第5月曜日」があっても,きっちり「隔週」の条件が求められる。この関数を使うと,月曜日に「缶」と「ビン」のどちらの回収があるかを表示する式は,以下のようになる。
=IF(WEEKDAY( A1 )=1; IF(MOD(WEEKNUM( A1; 1 ); 2)=0; "缶"; "ビン"); "")
もし缶とビンの回収日が逆の場合は,上記式の“=0”の部分を“=1”にするか,あるいは "缶","ビン" の記載位置を逆にしてもよい。
その年の「第1週」が何日からなのか,エクセルの WEEKNUM() 関数の定義では微妙に違うかもしれない。ただ,「第1週」はいろいろ考え方があり,たとえば「元旦を含む週」とか,「1月4日を含む週(新しい年に4日以上曜日を含む週)」とか,「その年の最初の月曜日を含む週」や,あるいは「仕事始めの日を含む週」などの場合も考えられる。こればかりは役所や企業などの組織の都合により異なる要因も大きい。
だから「週番号」の関数は,厳密な定義を気にする意味もあまりない気がする。だいたい「エクセルでは1月1日が『第1週』だから,絶対その週から仕事始めるぜ~!」的な働き方など,本末転倒でしょって。この手のソフトは,手間を省いたりして「働き易くするため」にあるわけだし。特に,この「隔週」という条件は,週ごとに1ずつ異なる数値が偶数か奇数かだけの判断だし,どーせ年末年始などはお休みでズレることもあるのだから,上記のように,“=0”とするか,あるいは“=1”とするか,年ごとに適宜変更して対応すればいいんじゃないかって話。
もし「ウチでは盆も正月も関係ねぇ! 厳密に隔週だ!」というなら手はある。以下の式なら「新年の第1週めが何日からか」に関係なく,厳密に7日ごとに0と1が交互に求まる。
=MOD(INT( A1 / 7 );2)
年末年始など,休日の場合に「以降を一週ずつズラす」のではなく,単純に「中止」となる場合は,これが使える。休日だけ,セルから式を削除すればいいわけだ。
逆に言えば,「以降を一週ずつズラす」には,IF() 関数内で“=0”か“=1”かの変更などが必要になる。
◆ 「予定表」のまとめ
いろいろな予定の条件を述べてきたが……ひょっとして「でも,その式を設定する日を探す手間が必要だから,同じじゃねーか!」と思っていたりしませんか? 説明してきたのは「それをせずに済む方法」でっせ。それでも「お前は何を言ってるんだ?!」状態かもしれませんが。
述べてきた式を単一セルに「全部」設定するんですわ。つまりこう。
=〈可燃ゴミの条件〉&〈不燃ゴミの条件〉&〈金属類の条件〉& 〈PET プラゴミの条件〉&〈缶/ビンの条件〉
述べてきた全ての条件式を「文字列」として連結してひとつの式にして,その式を全てのセルに設定する……つまり「コピーする」ことで,該当の条件に合致した日に回収するゴミだけ……たとえば「可燃ゴミ」とか「不燃ゴミ」などの文字が表示されるようになるわけですよ。
「全てのセルに同じ式をコピーすれば完了!」……マウスでドラッグするなどで 365 のセルにコピーすれば,1年分の予定表が数秒で作れる作業になるというわけです。なんてラクなのでしょうか!
じつはこれまでは,式の意味を分かり易く説明するため,回収曜日ごとの条件式を個別に作ってきたようなところもある。ゴミ回収ほど毎日いろいろあるわけではなく,「第○×曜日」のイベントが月にいくつかある程度の予定表は,述べてきた条件のうちいくつかを連結すれば済むことも多いだろうから,上記のように「文字列」として単純に連結しても,そんなに複雑にはならず,実用上差し支えないと思われる。
一方で,このゴミ回収のように,平日はほとんど,あるいは全曜日でほぼ必ず何がしかあるような予定表は,全ての曜日の条件を連結するとやたら長くなる。じつはそんな場合は,もう少しスマートな式にまとめることができる。以下のような感じ。
=CHOOSE(WEEKDAY( A1 ); "(日曜日)"; IF(MOD(WEEKNUM( A1; 1 ); 2)=0; "缶"; "ビン"); "可燃ゴミ"; CHOOSE(INT((DAY( A1 )+6)/7); "金属類"; "不燃ゴミ"; ""; "不燃ゴミ"; ""); "PET プラ"; "可燃ゴミ"; "(土曜日)")
説明の都合で行を分けたが,実際のセルへの設定は1行に記述する。また "(日曜日)" と "(土曜日)" は,意味を分かり易くするために記載したもので,実際に使う際は ""(空文字列)にしてしまっていい。
上記式なら,CHOOSE() 関数で最初に曜日を分けて考えるから,説明してきた各曜日の条件式の「WEEKDAY( A1 )=×」部分が要らなくなる。当然,毎週回収される「可燃ゴミ」と「PET プラゴミ」は,IF() 関数を使わずに書けることになる。
それ以外は,2行めの IF( …… ) で,月曜日に「缶/ビン」を交互に表示する(=隔週)。3行めの CHOOSE( …… ) では「第○水曜日」を分けて,○が1なら→“金属類”,以下2→“不燃ゴミ”,3→表示なし,4→“不燃ゴミ”,5→表示なし……となる。
こうして作った式を B2 セルに入れ,「オートフィル」で下にコピーすると,以下のようになる。
▼ 回収日を自動表示 |
◆ テキストデータを作る
さて,筆者が表計算ソフトで「ゴミ回収カレンダー」を作ろうとした目的は,「テキストで見れる」ようにしたかったから。しかし,このままでは「表計算ソフト」を起動しないと見れない。とはいえ,ここまでできたら,あとは「テキストとして」エディタやメモ帳などにコピペすればいい。
そこでもうひと工夫して,きちんと「△月○日×曜日」と記載されたデータを作ってみる。A列に日付の数値が,B列に述べてきた「その日に回収するゴミ」を求める式が入っている時,C列に「△月○日×曜日には何のゴミ回収があるか」を示すデータを求めるのは,以下の式。
=MONTH( A1 )& "月 "& DAY( A1 )& "日 "& MID("日月火水木金土"; WEEKDAY( A1 ); 1)& "曜日 "& IF( B1=""; "回収はありません"; B1 )
上記は,述べてきたように「日月火水木金土」あたりを置き換えれば他言語にも使えるが,日本語に限定していいならこう書くと短くなる。
=TEXT(A1;"M月 D日 AAAA ")&IF(B1="";"回収はありません";B1)
ここでは,もしB列が空文字だったら「回収はありません」と表示するようにした。
こうして作成したC列のデータを一部コピペしたのが以下になる。
10月 1日 木曜日 PET プラ 10月 2日 金曜日 可燃 (枝,褓) 10月 3日 土曜日 回収はありません 10月 4日 日曜日 回収はありません 10月 5日 月曜日 ビン スプレー ライター 古紙 古布 10月 6日 火曜日 可燃 (枝,褓) 10月 7日 水曜日 金属 小型家電 廃油 10月 8日 木曜日 PET プラ 10月 9日 金曜日 可燃 (枝,褓) 10月 10日 土曜日 回収はありません 10月 11日 日曜日 回収はありません 10月 12日 月曜日 缶 10月 13日 火曜日 可燃 (枝,褓) 10月 14日 水曜日 不燃 10月 15日 木曜日 PET プラ 10月 16日 金曜日 可燃 (枝,褓) :(後略)
実際は年末(12/31)まで求めた。1行めに述べてきた式を設定すれば,あとは下に「オートフィル」などでコピーするだけだから,3ヶ月分だろうと1年分だろうと,ほんの数秒でデータ作成は完了する。
別の地域や自治体のデータを作る場合でも,回収ゴミの曜日の条件を変更するだけで済むだろう。
ちなみに「褓」の字は「オムツ」を意味する字で「むつき」と読む。あまり使われない字なので意味を忘れるかもしれないが,どーせ子供のいない筆者にとっては関係ないから,ここでは「省略形」的に使った。
◆ 「テキストデータ」を作る意味
しかし,誰もがスマホを持ち,どこででも凝ったレイアウトのウェブページを見れるこのご時世に,「テキストデータ」を作ることに意味などあるのか……まぁ,筆者が作ろうとした理由は「表示が超重たい PDF
より素早く見れるようにしたい」からだが,ほかにも,視覚障害がある方など,「音読ソフト」といったツールでウェブ記事を「聞いている」人にとって重要なのだ。
ウェブ記事の標準形式は HTML と呼ばれるものだが,いくらでも凝ったレイアウトが実現できるぶんだけ,必ずしも「記載順に読めば分かり易い」状態とは限らない。どちらかというと,作成する側が「見てもらいたい順」に配置されることが多いのではないか。すると,広告やイラスト,カテゴリ分類のメニュー,担当部署や支部サイトへのリンク一覧などが最初のほうに並んだりすることになるだろう。
視覚に障害がある方は,そうしたウェブ記事の文字情報を,「音読ソフト」というものを利用して「聞く」こともあるわけだが,たいていのソフトは,おそらく「記述されている順」に読まれるだろう。すると,述べたようなレイアウトでは……そう,イラストは見れないから関係ないし,リンクなどはその先に必要な情報があるかどうかは分からない。そのウェブ記事の主題である本文の前にそうした内容があると,本文に辿り着くまでにたいへんな時間がかかってしまう可能性もある。
たとえ本文に辿り着いても,HTML で記載された「表」の内容など,単純に記載順に読まれた時に,内容が理解できるものになるかどうかは分からない。
ましてや PDF の場合,内部では,同方式で扱うのに都合のいい順番に文字の並び順が変えられてしまう場合もある。つまり,作成した PDF
を見て「文字は伝えたい順番通りに並んでいるな」と確認しても,その順番で読まれない可能性もあるわけだ。これが PDF に潜むリスク。
テキスト版を作り「本文のみを聞けるようにしておく」ことは,そうした懸念を減らす意味もある。それが「テキスト版」の重要性。
記述の仕方にも「配慮」が要る。たとえばゴミ回収カレンダーの場合は,見れる者なら,「10/21 水」とだけ書いてあって以降が空欄なら,「10 月 21 日の水曜は回収ないのね」と分かるだろうが,音読ソフトに読ませた場合,まず「10 月 21 日」と読んでくれるかどうか微妙だし,何より「水」は「みず」と読む可能性も大きい。「空欄」は読むものがないので,直ぐ次の日が読み上げられたりして,分かりにくくなることも考えられる。つまり「画面を見ずに音声で聞く人がいる」ことを想定するなら,「10 月 21 日 水曜日」と記述しておいたほうがいいだろうし,回収がないなら「ない」と書いておいて,それが聞けたほうが分かり易いだろう。空欄にせず「回収はありません」とわざわざ表示することも,その「空欄」を見れない人が音声で聞くことを想定すれば,ある意味当然というわけだ。
今これを読んでいるお役所をはじめとするサイト担当職員諸君! そこまで考えてサイト設計しているかね?……期待はしていないが。
だいたい,筆者の地域のゴミ回収カレンダーのテキスト版も,9月分までは市のウェブサイトで見ることができたから,おそらく同様な配慮があったのではないかと思われる……が! 10 月に入って見ようとしたら閲覧できなかった。間に合わなかったのか,それともそうした「音読ソフト」で聞いている人たちのことは忘れられてしまったのか……。
ちなみに,今この文章を筆者サイトで読んでいる場合は,URL の末尾に .txt(ドットティーエックスティー)を付加して読み直すと,本文だけのテキスト版が読めるシステムを使っている。詳細は以下を参照。
● 日付を扱う時に便利なその他の方法
ここまでしっかりと内容を見ていただいた方なら,簡単な応用式くらいもう作れると思うが,いくつか基本的な具体例を挙げてみる。
もし,牛丼屋のサービスデーだから「毎月 29 日を目立つようにしておきたい」なんて時は,こんな感じ。
=IF(DAY( A1 )=29; "牛丼屋サービスデー"; "")
たとえば「土日に『休業日』と表示する」くらいの応用は直ぐに考えられるでしょう。
=IF(OR(WEEKDAY( A1 )=1; WEEKDAY( A1 )=7); "休業日"; "")
上記の式は分かり易いが,少々長くなる難点がある。関数の繰り返し使用を避け,もう少し短くしたい場合は,こんな式でも OK。
=IF(WEEKDAY( A1 + 1 )<=2; "休業日"; "")
この式は「翌日が日曜か月曜」という意味になる。
また,「末日」の判断は,OpenOffice で「その月の日数」を求める関数を使って分かり易く書くならこう。
=IF(DAYSINMONTH( A1 )=DAY( A1 ); "月末調整日"; "")
エクセルでも使える EOMONTH() という関数は,月末の日付の数値を表すため DAY() は不要で,こう書けば使える。こちらは,区切り文字を ";" にすれば OpenOffice でも使える。
=IF(EOMONTH( A1, 0 )= A1, "月末調整日", "")
次節以降では,「ゴミ回収」には使いそうにないが,もう少し応用的で,知っていると便利な式について考えてみる。
◆ 2のつく日
自営業店の定休日とか,チェーン店のサービスデーなどは,こうした決め方をすることもあるかも。これはさほど難しくない。「一の位」が2ということは,十で割った余りが2だから,以下のような式で OK。
=IF(MOD(DAY( A1 ); 10)=2; "サービスデー"; "")
20 日から 29 日までも「2がつくから……」という扱いではないことが前提だけど。んなことしたら,サービスし過ぎだろって。
◆ 五十日(ごとうび)
「ごじゅうにち」ではない。
筆者がまともに働き始める前に「ごとうび」と聞いた時は,どっかの後藤さんが何かする日かと……は思わなかったが。まぁ,企業などが,何かと「区切り」に使いがちな,一の位が5かゼロの日のことらしい。
これもそんなにむずかしくはない。5の倍数だから,これでいい。
=IF(MOD(DAY( A1 ); 5)=0; "ごとうび"; "")
全ての「ごとうび」に何かする必要がある企業や組織などそんなにないかもしれないが,「道路が混む可能性が高いから……」通常より早めに行動する意識喚起などの対策には使えるかもしれない。
◆ 土日を避ける
たとえば「毎月 20 日が給与締め日」など,何らかの節目の日で問題になるのは,土日と重なる場合。それを避けるために「前倒し」か「先送り」する場合もありうる。祝祭日を避けることまで考えると,それらの日を記録しておく領域を確保し,そこを参照する必要が生じるため,ここで紹介できるほど簡単ではなくなってしまうが,祝祭日を考えなくてもいいなら,以下の式が使える。それでも,ちょっと複雑だが……。
=IF(AND(18<=DAY( A1 ); DAY( A1 )<=20; IF(WEEKDAY( A1 + 2 )<=3; WEEKDAY( A1 )=6; DAY( A1 )=20)); "給与締め"; "")
式の意味としては,「当日から2日前まで(18,19,20 日)がもし金,土,日曜のどれかなら金曜だけ,それ以外の曜日は 20 日が『給与締め』の日」という条件を示す。もし「給与締め」の日が 15 日なら,それぞれの数字を「18→13,20→15」に置き換えて使う。
週明けの月曜日にズラす場合はこう。
=IF(AND(20<=DAY( A1 ); DAY( A1 )<=22; IF(WEEKDAY( A1 + 1 )<=3; WEEKDAY( A1 )=2; DAY( A1 )=20)); "給与締め"; "")
こちらは「先送り」なので「2日後」までが条件になる。もし「給与締め」の日が 15 日なら,それぞれの数字を「20→15,22→17」に置き換えればいい。
「ごとうび」の土日を避けたい場合は,もうちょっと複雑。
=IF(IF(WEEKDAY( A1 + 2 )<=3; AND(WEEKDAY( A1 )=6; MOD( DAY( A1 )+ 2; 5 )<3); MOD(DAY( A1 ); 5)=0); "ごとうび"; "")
=IF(IF(WEEKDAY( A1 + 1 )<=3; AND(WEEKDAY( A1 )=2; 5<=DAY( A1 ); MOD( DAY( A1 ); 5 )<3); MOD(DAY( A1 ); 5)=0); "ごとうび"; "")
いずれにしても,「ハッピーマンデー」とかいう祝日が邪魔なので,通常は直前の金曜にするのが無難ではないかという気がするが……あ,プレミアム何ちゃら……ま,いいか。どーせ忘れられているし。
◆ 最終×曜日
その「プレミアム……」何ちゃらとは,何だったのか。まぁ,すっかり忘れられて,めでたしめでたしというところだろうか。
「プレミアム……」何ちゃらでなくても,「最終×曜日」に何かする必要がある場合も考えられる。これは「第5週」がある曜日とない曜日が毎月違うので,「第4×曜日で OK」とはいかない。
とはいえ「末日」を示す式は分かっているから,「その一週間前より後」を判断すればいいことになる。たとえば「最終金曜日」の判断は,以下のようにすればいい。
=IF(AND(DAYSINMONTH( A1 )-7<DAY( A1 ); WEEKDAY( A1 )=6); "プレ"; "")
=IF(AND(EOMONTH( A1, 0 )-7< A1, WEEKDAY( A1 )=6), "プレ", "")
式の意味としては「月末の7日前より後の金曜」ということになる。上の式のほうが意味的に分かり易いと思うが,下の式でも,区切り文字を ";" にすれば OpenOffice でも使える。
◆ 第○×曜日の翌日
筆者が前に住んでいた自宅近くの図書館の休館日は「毎週月曜日と,第3月曜日の翌日の火曜日」とかいう変な法則だったような気がする。これは必ずしも「第3火曜日」ではない。その月の1日が火曜日の時,第3月曜日は 21 日になるから,翌日の 22 日も定休日になるが,それは「第4火曜日」だ。
一見厄介そうに見える。が,じつはそんなに複雑な式にはならない。なぜなら,「前日が」第3×曜日かどうかを調べればいいだけだから。
=IF(OR(WEEKDAY( A1 )=2; AND(INT((DAY( A1 )+5)/7)=3; WEEKDAY( A1 )=3)); "図書館休館日"; "")
「第○×曜日」の○を求める式は INT((DAY( A1 )+6)/7) だが,この“+6”の部分を1つ少ない“+5”とすればいいわけだ。
● 多言語対応 (m17n)
さて,何度か「『他』言語に対応するなら……」と書いた。ネットの普及によって「それぞれの国の事情」というものも容易に知れるようになったためか,様々な国籍の人が相互に他国を訪れ,時としてそのまま滞在することも多くなって来ているような気がする。そうすると,やはり「言葉」の問題が起こるだろう。回収日を知る方法がないまま違う日にゴミを出されて散乱してしまったり,出す日が分からずに溜め込まれて「ゴミ屋敷」になってしまったりしては,近所迷惑になってしまう。せっかくそこが気に入って,わざわざ海外から来て住んでくれているのなら,それらの人たちに何とかしてその自治体から「ゴミを出す日」を知らせる方法があってもいいような気がする。そんな感覚から,日本語と英語以外の「他」言語を意識したわけだ。
既に述べたように,TEXT() という関数なら表計算ソフトに元々ある曜日や月の名前を表示する機能がそのまま使えるが,あくまで「英語」がメイン。日本語も表示するが,それは日本語向けにインストールしてあるからこそ。つまり TEXT() 関数でその他の言語向けデータを作りたいと思ったら……極端な話,それぞれの言語向けにインストールをしたパソコンを,対応させたい言語の数だけ用意しなければならなくなる。
でもそれは,TEXT() という関数を使うなら,の話。これまでの説明で,あえて TEXT() 関数を使わない式を挙げた理由は,もう察してもらえるだろう。これは「言語」に限らない。たとえば「幼児向け」のカレンダーを作るため曜日をひらがなで表示したい時は,CHOOSE() 関数を使って以下のようにすればいいのは,すぐ思い付くと思う。
=CHOOSE(WEEKDAY( A1 ); "にち"; "げつ"; "か"; "すい"; "もく"; "きん"; "ど")& "ようび"
これは,たとえ日本語向けにインストールしたパソコンであっても,TEXT() では対応できない。CHOOSE() 関数なら,他の言語に対応したい時も,この「にち,げつ,……」の部分を他の該当する言語に直せばいいことになる。
ただそれでも,「多」言語に対応したい時は,かなりの手間になる。
日本人は減っていくことが確定のこのご時世,少しでも自治体の人口減少を食い止めるには,たとえ外国人だろうと「住み易さ」を実感してもらうため,たとえば「市に一定割合以上住んでいる外国人の母国語には,なるべく対応する」といった方針を打ち出す必要も出てくるのではないか。すると,その施策として「ゴミ回収カレンダーの多言語対応」なども考える必要が出てくる可能性もある。
「たまたま職場にポルトガル語を使う人が数人いる」くらいならば,特定の「他」言語に対応するだけだから,上記「にち,げつ,……」の部分をポルトガル語に置き換え,カレンダーを一度作り直す程度で済むが,前述のような方針を打ち出した自治体の役所ではそうもいかない。対応させたい言語の数だけ,年度が変わる度にいちいち「にち,げつ,……」を置き換えたり,しかも「地域によって回収曜日が異なる」となれば,地域ごとにカレンダーを作り直す必要も生じ,かなりの手間だ。
では,「簡単な変更で,全体がパッと他の言語に置き換わる方法」などあるのか?……ある。といっても,どの言語でどんな単語を使うのか(可燃ゴミ→○○,不燃ゴミ→△△)の自動翻訳機能が表計算ソフトに備わっているわけではないため,それらの言葉の「訳語の一覧」は独自に作成する必要はあるが。そこを作れれば,方法はある。
表計算ソフトには,「間接参照」と「相対参照」という機能がある。「間接参照」というのは,セル位置を直接式内に指定するのではなく,主に,別のセルに記載された内容(文字列)などを元に参照する機能。そして「相対参照」というのは,セルの位置と共に「ズレ」を指定し,(下に)×行,(右に)○列だけズレた位置の内容を求めるもの。
全体としては,まず,「月の名前,曜日,回収ゴミの種類」について「言葉の一覧」を各国語ごとに作り,カレンダーの式でそれらの言葉は直接使わず,「間接参照」で指定した「言葉の一覧」から「相対参照」で引っ張り出して表示するようにしておく。そうすると「間接参照」で指定する「言葉の一覧」を変更するだけで,カレンダーで使う言葉全体が置き換わってくれるようになる。
少々高度になるが,以降の節でもう少し詳しく突っ込んでみたい。
なお,この章で使う OpenOffice の「シート名」の扱いもエクセルと異なるので,以下のように直して("."→"!")使って欲しい。
Langs.$C$1
Langs!$C$1
◆ 言語ごとの「言葉の一覧」 (m17n table)
まず,例としてこうした表を作る。
▼ 訳語の一覧シート「Langs」 |
A列は日本語,B列は英語,以降,フランス語,ドイツ語,スペイン語,ポルトガル語で,それぞれ下の各行に月名(January,February,……)と曜日(Sunday,Monday,……),あとゴミの種類(可燃ゴミ,不燃ゴミ,……)を,A列の日本語と同じ行が該当する外国語の単語になるように設定した。
そしてこのシートは「Langs」という名前にした。
なお,あくまでサンプルのつもりで,訳語は Google の翻訳サイトによるもの。どこまで正確か分からないので,これを元に自治体でデータ作って配布したりしないよーに。
◆ 間接参照 (INDIRECT)
「間接参照」とは何かと言うと,本来,セルの値の参照は,たとえば「=A1」など,セルの名前を式の中に記述するが,そうではなく,他のセルの中身の「文字列」を「セルの名前」として扱うもの。
たとえば以下の図では,D1 には前述 Langs シートの A2 セルの内容である「日本語」という文字が表示されているが,そこには該当のセルを示す式ではなく,隣の C1 セルを参照する式が設定されている。
▼ 間接参照の例 |
$マークについては後述するが,参照先はマークの付いていないセル名と同じ。たとえば $C$1 だったら C1 が参照される。その C1 セルには“Langs.$A$2”という表示があるが,これも,さらに左隣の B1 セルにある“A”という文字を元に,以下の式で作られた「文字列」だ。
="Langs.$" & B1 & "$2"
=INDIRECT( $C$1 )
INDIRECT( 値 ) という関数は,指定した値を「セルの名前」として扱い,そのセルの値を求めるもの。もし D1 セルに“=$C$1”と設定した場合,隣の C1 セルの内容はそのまま「ただの文字列」と解釈されて「Langs.$A$2」と表示するだけだが,“=INDIRECT( $C$1 )”と設定すると C1 の内容「Langs.$A$2」が「セル名」として解釈されて,Langs シートの A2 セルの値である“日本語”が表示されるというわけだ。
$マークはよく「絶対参照」と呼ばれるもので,セルとしては $ の付いていない C1 や Langs.A2 と同じ扱いになるが,他のセルにコピペしても参照するセルが変化しないという点が異なる。D1 セルに設定されている式を例にすると,以下のような違いになる。
- 絶対参照(コピペしても参照先が変わらない)
=INDIRECT( $C$1 )
↓(どこにコピペしても)
=INDIRECT( $C$1 )
- 通常の参照(これを「相対参照」と呼ぶこともある)
=INDIRECT( C1 )
↓(右の E1 セルにコピペすると)
=INDIRECT( D1 )
↓(もし下の D2 セルにコピペすると)
=INDIRECT( C2 )
通常の参照の場合,C1 セルは D1 セルの左隣なので,コピペした先でも必ず左隣のセルを参照するようにセルの名前が変化するわけだ。
◆ 相対参照 (OFFSET)
こちらの相対参照は関数のこと。
OFFSET( セル範囲; 下方向; 右方向; 行数; 列数 ) という関数は,指定したセル範囲の位置から下,右それぞれに何セル分かズレた位置のセル内容を求めるもの。行数と列数を省略すると,最初に指定したセル範囲と同じになる。1つのセルを指定した場合は,値も1つになる。
前節の INDIRECT( $C$1 ) では,Langs シートの“日本語”と書いてあるセルが指定されていたわけだが,それを OFFSET() 関数に指定し,そこから 10 行下の値を求めれば“10 月”になる,というわけだ。
▼ 「10 月」を表示させている仕組み |
実際は「10」ではなく,MONTH(A2) という関数が使われているから,A列の日付が他の月の場合も正しい月名を表示する。つまり,こう。
OFFSET( INDIRECT( $C$1 ); MONTH( A2 ); 0 )
Langs シートでは 12 ヶ月分の月の名の下に曜日が続いているから,曜日を表示させるには 12 行分下を相対参照すればいいことになる。
OFFSET( INDIRECT( $C$1 ); 12 + WEEKDAY( A2 ); 0 )
間にスペースを入れ「日」をはさんで上記を連結させれば,月,日,曜日を表示させることができる。
=OFFSET( INDIRECT( $C$1 ); MONTH( A2 ); 0 )&" "& DAY( A2 )&" "& OFFSET( INDIRECT( $C$1 ); 12 + WEEKDAY( A2 ); 0 )
◆ 一ヶ所変えるだけで他言語に対応!
「仕上げ」としては,回収ゴミの種類についても,述べてきた「間接参照」と「相対参照」の関数を使って表示させること。たとえば「可燃ゴミ」と表示させたい時は,“日本語”と書いてあるセル(A2)から下に 20 行分ズレた位置(A22)にあるわけだから,こうした式にする。
OFFSET( INDIRECT( $C$1 ); 20; 0 )
つまり,全てのゴミ回収日を示す式の "可燃ゴミ" と記述してあるところを,上記に置き換える。他のゴミについても,20 の数を変更して対応する。たとえば「不燃ゴミ」なら 21 にする。
さて,ではこうして作成した「ゴミ回収カレンダー」で,C1 の値を変えるとどうなるだろうか。C1 は左の B1 セルにある“A”の値を参照しているから,ここを,たとえば“B”にすると,こうなる。
▼ C1 セルが“Langs.$B$2”になると…… |
重要なのは,変更したのは B1 セルの内容を“A”→“B”にしただけで,カレンダーのC列に設定した式などの内容は一切変更をしていない点。それは,カレンダー側に全く手を加えなくても,他言語に対応したカレンダーが作成できることを意味する。
同様に B1 セルを“C”にすれば全てがフランス語に,“D”にすればドイツ語になるであろうことは,言うまでもないと思う。
対応させたい言語を増やしたい時は……? 言語対応表に新しい列を付け足すだけで済むことは,想像してもらえるだろう。つまり,将来の国際化への対応もかなり容易になると考えられないだろうか。こうした手法により,多言語への対応が最低限の変更で実現できることになる。
◆ 「国際標準文字コード」を考えるべき
ゴミ問題は日本だけの話ではない。実際,輸入加工食品のパッケージなどを見ると,産地がどこの国だろうと,そのパッケージがどんな素材でできているのか,だいたい似たようなマークが付いている。おそらく消費の多い国に輸出されている食品などは,その国の法律に合わせて,リサイクルやゴミ処理用のマークを付ける必要に迫られるから,そうした対応になるのだろう。
もう,どこの国でもゴミ問題はあるのだから,その手のマークは国際的に共通化していいレベルではないのかと思う。実際,衣類の洗濯扱いマークについては,日本も最近,国際標準に沿った表示にするよう変更された。末端の消費者にとっては「たかがマークくらいで」という感じもするが,輸入衣類を扱う業者にとっては,輸入した全ての衣類に日本仕様の洗濯扱いマークを付ける手間が省けて,スゴい経費の節約になるはず。それだけ安く買える可能性も高まり,消費者にとってもプラスではないだろうか。ただ「世界共通」ではあるらしいが,専用文字コードは定められていないみたいだが。
海外メーカーの食品の場合も,プラスチック製の包装には「プラ」のマークが付いていたりするが,つまりそれは海外のメーカーにわざわざそのマークを付けてパッケージを印刷するようお願いしているはずだ。
もしそうした「包装素材」のマークが国際標準化されれば,輸出国を増やす度にリサイクル用マークを追加してパッケージを作り直すコストを減らすことができるから,もっと安く,パッケージ素材マークで悩むことなく,様々な国の食品を買えるようになる気がするのだが……。
じつは,リサイクルのためのマークは,既にいくつか「フォント」のコードが割り当てられている。
♳ (U+2673,♳)
上記は,リサイクルを示す矢印で作られた三角形の中に,数字の1が書かれているが,2以降も ♴ ♵ ♶ ♷ ♸
……などいくつかある。日本以外では,既にある程度決まっているものなのか……と思いきや,どうやらアメリカ用の分別マークのようだ。
一方,日本では,缶や包装パッケージに記載されているリサイクルのための素材を示すマークには,「スチール,アルミ,プラ,紙」とか,思いっきり日本語が使われている。もう少し素材が何であるか分かるような「図」を考えればよかったのにと思うと,何だか残念にも思う。
その点,カレンダーは……少なくとも先進国では西暦の年月日と曜日は,表現は違うものの共通しているわけだが,では「曜日」を示す世界共通のシンボルなどあるのだろうか? 考えようによるが,フォントのコード U+2640 あたりに以下のようなマークが割り当てられている。
☼ ☽ ♂ ☿ ♃ ♀ ♄
太陽の印として「☉=U+2609」が使われることもあるようだ。
でも,知っていないと分からんわな。ただ,こうしたものは「母国語と併記する」期間が数年間ほどあれば,自然と認識されるようになるのではないかとも思う。
では「月(Month)」を示すシンボルは? これも考えようによるが,同じフォント・コードあたりに以下のようなマークの割り当てがある。
♑ ♒ ♓ ♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐
一般的には牡羊座(♈)が最初の扱いだが,山羊座(♑)に「1月生まれ」が多いので1月を意味する記号として扱うと,以下,水瓶座(♒),魚座(♓),牡羊座(♈),牡牛座(♉),双子座(♊),蟹座(♋),獅子座(♌),乙女座(♍),天秤座(♎),蠍座(♏),射手座(♐)の順番になる。
ただこの記号,フォントによりけっこうデザインが異なる。使用しているフォントが異なれば,見え方がかなり違ってしまう可能性も高い。
まぁ,月はどこの国でも数字で書くこともあるから,数字で分かるならそれに越したことはないだろうが。
ちなみに,U+32C0 以降にはこんな文字コードも定められている。
㋀ ㋁ ㋂ ㋃ ㋄ ㋅ ㋆ ㋇ ㋈ ㋉ ㋊ ㋋
1文字で「○月」と表示される文字コードであるが,これらが,もし日本語以外のフォントで表示した時,その国の月を示すものとして読めるようにするための割り当てなのだとしたら非常に意味があることだと思った。つまり日本語フォントで見ると「1月,2月,……」の表示だが,英語フォントでは同じ文字が「Jan,Feb,……」と表示されると。同様に,この文字を使ったファイルを別の国の人がその国用のフォントで見ると,その国の言語で該当する月が表示される……そういった文字なら「訳す必要がなくなる」わけだ。だが,ザッと検索した限り,そうした記事は見当たらなかった。日本語専用の文字ということか……。
様々な感情を表す顔文字やら,動物の絵文字とかを割り当ててばかりいないで,世界の産業活動で共通で使われるような,たとえば洗濯表示や,月と曜日,ゴミ処理時に必要になる素材などの共通専用文字コードをとっとと割り当てればいいのにと思う。
オリンピックで何の競技かを示す「ピクトグラム」という絵記号は,前回の東京オリンピック(1964)で初めて使われたとか。また,非常口を示す緑色のピクトグラムも,日本発祥らしい。どちらも今はどこの国でも使われている。「どの国の人でもパッと見て分かるように」という「配慮」が国際的に認められたからだろう。
そうした意味でも,日本のリサイクルマークが日本語ってのは,少々残念な感じがしている。この国に「配慮」はなくなってしまったのか。
◆ サイトで配布する際に高効率な方法
じつは,ゴミ回収日カレンダーのようなものは,紹介してきたような方法で「各言語」のデータを作成しておいて,それをその自治体サイトで配布するようなやり方は,あまり効率がいいとは言えない。というのは,自治体もある程度の規模になれば,地域により回収日が異なることも普通にあるだろう。となると,回収カレンダーのデータを「地域数×言語数」だけ作成しなければならない。それだけのデータを保存しておく領域も必要になるが,全ての地域に,全ての外国語を使う人が住んでいるとも限らないから,もしある外国語の人が住んでいない地域があると,その言語のデータを作っておいても「誰も見ない」可能性もある。だからと言って,いつそうした人が移り住んで来るのかも分からないから,無駄と分かっていてもとりあえず作っておく必要性もある。それを年度ごとに行なうことになり,もし修正が必要となれば,作ったデータの数だけ作り直さなければならない……などなど,結局,効率的にいろいろと難があるのは想像できるだろう。
ではどうすればいいのかと言うと,できれば「オンデマンド」で作成する仕組みのほうが効率はいい。「オンデマンド」……簡単に言うと,要求があった時「その時点で作られる」仕組みで,ここでは,紹介した「多言語対応の方法」をウェブサーバ上に構築するようなもの。回収日を見るウェブページで言語と地域を選択すると,その設定でゴミ回収カレンダーのデータがサーバ上で作られ,閲覧者に送られるような感じ。
すると,まず「全ての地域×言語」の数だけカレンダーを作って置いておく領域が要らない。もし,ある外国語の人が住んでいない地域があり,データを見ようとする人がいない場合は,そもそも「作られない」ことになる。で,もしそうした人が移り住んで来て,その人がゴミ回収日を確認するために自治体のサイトを訪れた時,初めて,その地域でのその言語の「回収カレンダー」が自動的に作られることになる。回収の予定を作成する側は,どの地域にどこの国の人が住んでいて,何言語用にカレンダーを作るべきかを気にする必要はなく,ただサーバに予定の設定をすればいいだけになる。
そして修正は,述べてきた方法では,「ゴミ回収日の法則の式」と,「訳語の対応」が別のシートで管理されていて,どちらか片方を変えれば,それに従って全ての回収日カレンダーが全ての言語で修正される。同様な方法でサーバ処理ができれば,たとえば「第2・4水曜日の回収だった不燃ゴミが第1・3水曜日になる」なら,サーバでその「法則」の設定さえ変えれば,全ての言語データで修正が済むことになる。
何より,「日本語」とそれに対する各国語の「訳語」が一致していれば,回収日が正しいかどうかを確認するには「日本語」だけのチェックで済むようになる。「訳語が正しく一致していれば」だが。
ちなみに,「筆者サイトでは URL 末尾に“.txt”を付けて読み直すとテキスト版が読める」と書いたが,じつは,サーバ上にあるのはそのテキストデータだけで,閲覧者が該当の記事を見ようとした時,サーバ上で HTML が作成される仕組み。つまり,「オンデマンド」で作られるため,やはり記事ごとに HTML で保存しておく領域が不要なのである。
サーバ上でいろいろできると,必要な人が,必要な時,必要なデータを,必要なぶんだけ作って提供できるため,効率がいいというわけだ。これが「オンデマンド」によるウェブページ生成の醍醐味。
● おわりに
こういうアイデアを紹介するのは,複雑な思いもある。
というのも,たとえば紹介したような表計算の使い方を知って,実際に利用した時,果たして効率は上がるだろうか,下がるだろうか。まぁたいていは上がるだろう。下がることはないと思うが,では「報酬は」上がるだろうか,下がるだろうか。
もし「ゴミ回収カレンダーを多国語に対応させたテキスト版を作る」という作業を考えた時,どれほどの時間がかかると予想するだろうか。述べてきたような方法を使わなかったら,1年分を日本語以外の言葉に訳すのに「3時間で終わる」と思うだろうか。それでも早いかもしれないが,仮に3時間だとしよう。
しかし,もし説明してきた方法を使えば,ひょっとすると数分で済んでしまう可能性もあるわけだ。今まで3時間かかっていた作業が,たとえば 10 分弱で済んだとすると,20 倍ほど効率が上がったことになるわけだが……では,報酬は 20 倍もらえるだろうか。
「何をバカなことを言っているのか」と思われるだろう。20 倍もの報酬が出るわけない。それはつまり「同じ成果」に対する報酬は下がることを意味する。報酬を下げたくなければ「効率を上げてはいけない」……これが「鉄則」であり,効率を上げたい者は相容れない社会常識。効率を上げるアイデアを紹介するのは,複雑な思いだ。
そもそも,政府が実現を謳う「同一労働,同一賃金」を文字通り解釈するなら,たとえどんなに時間が短かかろうとも,成果が同じなら同じ対価が支払われていいはず。
20 倍のスピードで作業をした人に,20 倍の報酬が支払われないのはなぜか。「いくら何でも 20 倍は……」というのが,大半の「感情」と思われる。しかし,報酬が「感情で」決められていいのか。筆者に言わせると,そのほうが問題に感じる。
他の人が3時間かかる作業を 10 分ほどで終わらせてくれたということは,他の人に 170 分ほど別の作業をする時間を作ってくれたようなもの。今回のように,表計算に式を埋め込んで「他の人も使える」ようにしたファイルを作ってくれたような場合,20 倍……とはいかないかもしれないが,他の人の効率も数倍ほど上がる可能性もある。つまり,他の作業も含め,全体としての効率も多少は上がることになるだろう。
しかし,他の人も含め全体の効率をどんなに上げても,「時給」換算で報酬が決められる今の制度では,報酬は上がらないのだ。でも効率が上がれば,同じ時間で多くの作業ができているはずだ。なのに,支払われる報酬がそのままということは,その「組織全体として」は得しているはず。ではその「得した分」はどこに消えているのだろうか……。
会社にもよるだろうが,企業の「内部保留」は億単位になるらしい。「大企業ともなればそれくらいあるだろう」と感じるだろうか。「億」とは「社員一人当たり」の話だ。「まさか……」と思った方は,「内部保留,社員一人当たり」などのワードで検索した記事を参照のこと。
最近,某通信会社が「大赤字」を出したとか言って,社長が陳謝したなどというニュースを聞いた。「利用者への出血大サービス」……ではなく,企業買収などでの損失らしい。別の通信会社は「ナントカ口座」という決済システムで多大な不正使用が発生し,勝手にお金を使われた利用者の被害を埋め合わせるためにバタバタしているという話も聞く。他の金融会社では,グループ会社の保険で不正契約が発覚し,「ひとりひとりに事情を説明」しに行くとかって話らしい。どれも多大なコストがかかるのではないだろうか。
一方,では社長をはじめ経営者の報酬はどうなるのか。「責任をとり今年は全経営者無報酬にします!」なんて話は聞かない。どんなに赤字でも,どんな不祥事を起こしても,報酬だけは持っていくのだろう。
「効率を上げてくれた人にも,上がった分の報酬は支払わずに済む」ということは,入ってくるお金と内部保留を増やせるのだから,それだけお金で解決し続けることができるうえ,経営者は,前述のような失敗を何度繰り返そうと「経営者」としての報酬は受け続けられる。つまり「お金が入ってくるうちは反省をせずに済む」的な感覚。これにより,末端の工夫で生み出した利益を経営者が不祥事で消耗する……みたいなループが固定化される。「何とかペイ」で,似たような失態を何度繰り返しているのか。それが事実なのだ。最初と最後をつなげると,「効率が上がっても報酬を上げずに済む構造が,失敗を繰り返す経営者をいつまでも居座らせている」ような感じ。こういった実態は問題視されず,半ば「常識」みたいな扱いである一方で,「報酬を 20 倍上げるなんて非常識」的感覚は普通に植え付けられている。だから「問題に感じる」のだ。「効率を上げた人にその分だけ報酬も上げる」ことと,「大赤字や不祥事を起こした経営者も責任は追求されず報酬を受け取り続けられる」こと,今「常識/非常識」として扱うべきは逆ではないだろうか。
末端で働く人たちの工夫によって効率が上がっても,それら工夫した人に「効率が上がった分」の報酬は渡されない。会社や組織の「儲け」や「成果」は増すだろうが……それはどこに消えているか,なぜ「格差が拡大」しているのか,それは誰の責任なのか,もっとハッキリさせる仕組みが必要ではないかと思う。
それで「働き手が足りない」と言いつつ,他方で「経営難」とか言って早期退職を募っているのが,今どきの企業だ。少しは考えるチカラのある者がこういった企業経営者の姿勢を見れば,「そこで働いて功績を上げよう」なんて思うわけない。すると,その企業で働き続けられる人たちというのは,「考えるチカラ」がある人とない人のどちらが多くなるだろうか。将来「経営者」にまで登りつめるのも,そこで働き続けられた人だとしたら……この先の日本の未来がどうなるか,今のままでいいのか考えるべきだと思う。もう一度言いたい,「20 倍の効率で成果を出した人には,20 倍の報酬が支払われてもいいのではないか」と。
「そんなことを言っていたら仕事できないだろう」と思われそうだ。実際,筆者は現在,仕事をしていない。昨年(2019)まで障害者向けにパソコン指導などをしていたが,新型コロナウイルスの影響で,現地へ出向いての指導ができなくなってしまったため,ほぼ無収入だ。
最初に働き始めた職場の仕事は,ソフトウエアの設計だった。初めての職場で「慣れ」もないだろうとのことで,3つのパートに分け,そのうち1つを筆者が,他は先輩(と言ってもかなりオッサン)が3ヶ月かけて担当する予定にしたが,十代からコンピュータに触れてきた者と,ハードウエア畑一筋でソフトは片手間で作っていたオッサンとの効率の差は歴然。1ヶ月ほどで,全パートを筆者一人で形造る結果になった。「2人×3ヶ月→1人×1ヶ月」だから単純には効率は6倍だが,その月,最初に提示された報酬の額は 14 万ほど。「やることはやった」と主張し,結果的にもう少しもらえたが,やはり長続きはしなかった。
少しあとに非常勤で働いていた児童福祉施設では,普及し始めたパソコンの調整などを担当した。しかし,筆者の提案はかなり却下された。当時はまだパソコンの本体と画面(ブラウン管)が別々のタイプが主流だったが,本体が壊れ処分する際に,「画面は残しておくべきです」と主張したが聞き入れられなかった。案の定,数ヶ月後に別のパソコンの画面側だけ壊れ,購入のため買出し担当の正規職員が中古屋巡りをしていた。残しておけば,その手間と購入の出費などなくても済んだ話だ。
あまり聞き入れられなかったが,他にもいろいろと提言したと思う。それが嫌われたのか,数年後「雇い止め」を食らった。筆者としては,「わざわざモニタだけ買う」必要に迫られるような手間やコストをなくすなど,効率を上げてやりたかっただけなのだが。そのワリには,雇い止めの理由は「財政難」とか言われたけど。
だから,「そんなこと言っていたら仕事できない」……というのは,その通りである。どちらかというと「仕事をさせてもらえなくなる」と言ったほうが正確か。日本の企業や組織では,適切に報酬を受け続けたければ「効率を上げてはいけない」のは「鉄則」なのである。この記事で紹介した方法を実際に活用し,グンと効率アップを成し遂げた方が,業務をドドドーっと増やされ消耗させられたり,上司や周囲から疎まれたりしないことを祈るばかりだ。
矛盾のある言行に対し多大なストレスを感じる筆者としては,普通に働くのはむずかしいだろうと思っている。たとえば,前述したような,「人手不足だ」と言いながら片や「希望退職」を募っている会社なんかで働く気など起きないし,ましてや,直属の上司が,他の人と同じ成果に対して同じ評価や報酬を与えない人だったりすると,ストレスに感じて直ぐ辞めることになるだろう。
だからといって,「同一労働,同一賃金」ひいては「同一成果,同一報酬」で働ける職場があるだろうか。矛盾のない「言行一致」した指示を出せる上司の揃った会社があるだろうか。今の日本で見つかる可能性は,限りなく低い。それを探しているうち,消耗して終わってしまうような人生のほうが寂しい気がする。
まぁやろうと思えば,説明してきたような表計算の式を作ってメールで渡す「アウトソーシング」とか,式の使い方や,作り方の指導に行ったりするくらいはできるが,そうした業務が有用と思われる職場ほど,「有用と思っていない」か,あるいは「そうした大幅な省力化や効率化が図れることを知らない」ことが多いような気もする。この記事で説明したような「予定表の自動作成」や「多言語化」について「方法があるのは知ってたぜ!」という方がどれほどいるだろうか。できると知られていないから,どこからもお声もかからないのだろうと想像している。
では,それを知った今,この方法を使おうと思うだろうか? 日本の労働効率は先進国中ずっと最低のままらしい。そらそうだろうと思う。
さて,今回題材にした「ゴミ回収カレンダー」というのは,自治体などが主体となって取り決めることだが,もし今この記事をそれらお役所の職員の皆様にお読みいただいていたとしたら,お役に立つだろうか。
この記事のアイデアを利用して作業すれば,同じ成果を出すために,利用しないよりは手間は省けると思う。つまり,その職場で「時間をかけずに済む」ことになり,ある意味「アウトソーシング(外注)」するのと同様の効果があると思う。
そこで,たとえアイデア考案者が無収入だろうと何だろうと,黙って使って自分の会社が儲かりさえすればいい低意識民間企業はさておき,少なくとも税金から報酬を得ている皆様におかれましては,政府の方針である「同一労働,同一賃金」を踏まえて対応していただけると考えております。格差の拡大も「社会的問題」とされている昨今,その問題を大きくするような対応をしないことも,そうした皆様の責任と考えておりますが,いかがでしょうか。この手のお手伝いのご相談はいつでもお待ちしておりますので,何卒よろしくお願いいたします。
それともやはりアイデアだけ黙ってこっそり使うのでしょうかねぇ。
あ~,こういうアイデアを紹介するのは,複雑な思いですわ。