浅野直樹の学習日記

この画面は、簡易表示です

令和4(2022)年司法試験予備試験口述再現(2日目・民事)

令和4(2022)年司法試験予備試験口述再現(2日目・民事)です。

 

帰宅して一晩寝てから作っているので忘れている部分があり、正確な再現ではありません。

 

本番はかなりグダグダだったのですが、読めるように補正しています。

 

主査の発言を地の文で、私の発言を――以下で、その他の内心の動きなどを()内で記載しています。副査は一言も発しませんでした。

 

(ドアのノック、ベルの音、○室○番ですの後)

パネルを見ながら聞いてください(パネルには、令和4年4月1日AはXに本件土地を売って登記を移転した、本件土地に賃借権が付いておらずXは本件土地を自由に利用するつもりだった、Xは本件土地を見に行かず建物が建っていることに気づかなかった、令和3年4月1日YはAから賃借していた本件土地に本件建物を建てて登記を経由した、といった内容が書かれており、その内容が主査により読み上げられた)。
――はい(状況がわからないということはないし、この問題に当たったのはラッキーかも。これは借地借家法でYの賃借権が対抗できるからXは負けるのでは)。

XはYに対して建物を収去して本件土地を明け渡すことを求めたいです。Xから相談を受けた弁護士Pは、Yに抗弁が成立するのではないかと考えました。それは何ですか。
――(訴訟物や請求の趣旨を言わせるのではないのですね)Yは対抗できるという抗弁です(Yが借地借家法で賃借権を対抗できそうだということが頭から離れずこのように言ってしまう)。

対抗関係ですか!?
――(主査はかなり不機嫌そう)いえ、本件土地についてXとYは対抗関係に立ちません。Yは有効な賃借権があり…

ということは賃借権に基づいて占有するという抗弁ですか。
――はい、賃借権に基づく占有権原の抗弁です(最初の質問でかなり時間を浪費して主査に答えを言わせてしまったけれども、副査がチェックした動作が見えたので、おまけでクリア扱いかなと思う)。

弁護士Pは、その抗弁が成立するかどうか確かめることがあると思いますが、それは何ですか。
――(建物所有目的であると思い込んだ上で借地借家法の除外規定を念頭に置いて)AY間の本件土地の賃貸借が一時利用目的かどうかを確かめます。

建物所有目的かどうかを確かめるということですね。
――(あ、そこからの確認か。善解してくださったのですね)はい(副査が何か言いたげなようにも見えたが結局何も言わず)。

Yは、自宅を建造するという約束で本件土地を賃借していたのですが、民泊を始めました。Xはどのような主張をしますか。
――(主査が「ちんじゃく」と発音していたことが印象に残る、「ちんしゃく」じゃないのか)用法義務違反を理由として賃貸借契約を解除します。Aはそのような解除ができ…

用法「遵守」義務違反ですね。あなたは今Xが解除できるということを言ったと思うのですが、Xが賃貸人になることに法律上の根拠はありますか。
――(義務の正確な名称と、解除の主体をAと言ったのをXと善解してくれたのですね、本当にありがたいです。自信を持って)民法です。

条文はわかりますか。
――六百何条かと記憶しておりますが、何条かまではわかりません。

それはどのような内容ですか。
――(一般論ではなく本件を思い浮かべて)土地を売買、譲渡したときに、賃貸人の地位が譲渡人に当然移転する…

土地だけですか。
――(主査は不満げ、しかし理由がわからず)いえ、土地だけでなく建物でも同様です。

そういう意味ではなくて。まぁいいや。Xは他には何か必要ではありませんか。
――(賃借人が賃料の二重払いを避けるため?)登記が必要です。

Yはどうですか。売買は賃貸借を破るのではないですか。
――いえ、賃借人(ちんしゃくにん)Yには本件土地上にある本件建物の登記があり、その日付がXより先なので、借地借家法で対抗できます(これが最初から言いたくて仕方なかった)。

賃借人(ちんじゃくにん)ですね。Xが主張する請求の訴訟物を言ってください。
――(やはり「ちんしゃく」ではなく「ちんじゃく」なのか。この発音は採点には関係ないはず。この流れだと所有権に基づくのではなく賃貸借契約終了に基づくはずだから)賃貸借契約終了に基づく建物収去土地明渡請求権です(建物収去を強く意識してこのように言ってしまいました)。

もう一度言ってもらえますか…賃貸借契約終了に基づくというのはそれでよいので。
――(主査は不満げ)賃貸借契約終了に基づく…目的物返還請求権です(言葉が出てきてよかった)。

そうですね。それではパネルを裏返してください。賃貸借契約終了の原因の要件事実を言ってもらいます。パネルを黙読してください。
――はい(パネルの裏側には、AY間の賃貸借契約の内容、Yが民泊として利用していること、X代理人Pが民泊としての利用をやめるように内容証明郵便を送ったこと、X代理人Pが賃貸借契約を解除するという内容の内容証明郵便を送ったことが書かれている。30秒程度で黙読)。すみませんが、もう一度質問をお願いできますでしょうか。

賃貸借契約終了の原因の要件事実を言ってください。
――まず賃貸借契約の成立…

終了原因事実だけでいいですよ。
――はい。(パネルの文言をそのまま読み上げて)X代理人弁護士Pは…

代理人弁護士Pというのは必要ですか。
――すみません、必要ないです。Xは、令和4年○月1日、Yに対し、内容証明郵便で…

内容証明郵便というのは必要ですか。
――いえ、すみません。不要です。Xは、令和4年○月1日、Yに対し、「(民泊としての利用をやめるようにといった内容のパネルの文言そのまま)」と伝えた。

「伝えた」ですか。もうちょっと他に言い方はありませんか。
――(主査が微妙な顔をしている、どうしようか)伝達した、意思表示した…

「催告」ですね。
――(その言葉がほしかったのか。もうちょっと誘導してもらえたら言えそうだったのに)はい、催告です。

それと、○月1日でよかったですか。民法では到達主義で…
――何度もすみません、○月2日です(主査を遮ってしまってすみません。一刻も早く早く訂正したかったものでして)。

他には何ですか。
――Xは、令和4年△月4日、Yに対し、「(解除するといった内容のパネルの文言そのまま)」と伝えた、意思表示した。

○月4日ですか。
――(また同じ間違いをしてしまった、どこまでパネルを棒読みして、どこから自分で考えるのかの振り分けが難しい)すみません、5日です。

それと?
――経過です。(この場合は到来ではなく経過ですよね)令和4年○月15日は経過した。

それだけで足りますか。
――(パネルの裏側に書いてあることで使っていないのは…最初の契約内容の部分か)AY間の賃貸借契約は、「(自宅として利用するといった内容のパネルの文言そのまま)」を特約としていた。

そうですね。これで最後の質問です。
――(副査の手が動いたし一応クリアなのかな)はい。

パネルは表にしてもらってもいいですよ。
――(パネルを表に戻す)はい。

Yは民泊として利用する許可をAから得たと言っていますが、Aは民泊として利用したいと頼まれた記憶はあるが承諾した記憶はありません。Yから依頼された弁護士Qは、Aに対して、承諾したという内容の証言をしてもらうようにお願いすることをYから求められています。この場合に、依頼者について考慮すべきことを明らかにしつつ、どうすべきかを答えてください。
――(法曹倫理か、これは状況がイメージしやすいかも)Qは、依頼人の利益を尊重すべきだということを考慮しつつ(主査満足げ)、他方で偽証罪の教唆をすることができないということも考慮して、Yに丁寧に説明すべきだと考えます。

説明するだけですか。
――説明をした上で、内心に反する供述を証人尋問ですることは偽証罪に該当し、私としてそのお願いをAにすることはできかねますと…

要は断るということですね。
――(それくらい簡潔な答えを求めていたのか)はい、断るということです。

以上です。お疲れさまでした。
――ありがとうございました。

(部屋から退出する)

 

直後は落ち込みました。最初で大きく躓いたのがよくなかったです。聞かれていることに対して的確に答えないといけません。

振り返ると民事訴訟法についての問いがなかったように思われますので、時間がかかりすぎて途中省略されたのかもしれません。

それでも対話をして食らいつくという姿勢は見せることができましたし、58はなくて59かなと思いたいです。

 



令和4(2022)年司法試験予備試験口述再現(1日目・刑事)

令和4(2022)年司法試験予備試験口述再現(1日目・刑事)です。

 

帰宅してから作っているので忘れている部分があり、正確な再現ではありません。

 

本番はグダグダだった部分もある程度きれいに補正しています。

 

主査の発言を地の文で、私の発言を――以下で、その他の内心の動きなどを()内で記載しています。副査は一言も発しませんでした。

 

(ドアのノック、ベルの音、○室○番ですの後)

今から事例を言うのでよく聞いてください。30代男性のAはバイクに乗り、歩いている20代女性Vのバッグを奪いました。そのバッグの中には現金2万円が入った財布と携帯電話が入っていました。女性はケガをしたりはしていません。何罪が成立しますか。
――窃盗罪が成立します。

強盗罪は成立しませんか。
――はい、成立しません。

それはなぜですか。
――反抗を抑圧するに足る暴行を加えていないからです(主査は満足げ)。

窃盗罪の成立のためには、財物の窃取以外にどのような要件が必要でしょうか。
――不法領得の意思です。

不法領得の意思とは何ですか。
――その財物の用法に従って利用処分する意思です。

不法領得の意思はその一つだけですか。
――その財物を占有している被害者を排除するという要件も必要です(主査がほっとした様子)。

Aは現金だけ取ろうと思っていました。バッグや財布や携帯電話はすぐに川に捨てました。窃盗罪はどの範囲で成立しますか。
――(自信はないけれどもこの前フリからすると)現金のみです。

そうですか…それではバッグの中に現金が入っていなかった場合には窃盗罪が成立しませんか。
――(主査は不満げだし、この場合に成立しないのも変なので)いえ、成立すると考えます。

どうしてですか。
――現金は財布の中に入っているので、財布も窃盗罪の対象となります。

バッグと携帯電話はどうですか。
――現金が入った財布がバッグの中に入っているのでバッグについても窃盗罪が成立します。携帯電話、携帯電話…については成立しません。

それでは犯人の主観により窃盗罪が成立したりしなかったりするのですか。
――(主査不満げ。ただ、先ほどの理屈からすると成立しないと言いたいので)すぐに川に捨てたという客観的な事情から判断します。

わかりました。それでは事例を変えて、最初から携帯電話も取るつもりだったとします。携帯電話を盗んでから家に持ち帰って破壊しました。何の罪が成立しますか。
――何の罪も成立しません。

器物損壊罪は成立しませんか。
――はい、成立しません。

それはなぜですか。
――不可罰的事後行為だからです。

それはどういうことですか。説明してください。
――この場合は最初から携帯電話を盗むつもりだったので、それを窃取した時点で窃盗罪が成立します。そしてそれでもう評価されています(拙い説明だけれども伝わっただろうか)。

話は変わって、Aが逮捕されて10日間勾留されました。検察官は10日の勾留延長を請求しています。あなたが裁判官だったとして、どのような要素に着目して勾留を延長するかどうか判断しますか。
――起訴するかどうかを判断するために、捜査の進捗具合や、さらなる捜査が必要かどうかに着目します。

今後必要な捜査の所要見込時間も関係ありますか。
――(そこまで言ってくれるんですね…)はい、必要だと考えます。

どうしてですか。
――窃盗罪でしたら最大であと10日しか勾留を延長できないからです。

それでは裁判官のあなたは3日で捜査が可能だと判断しました。検察官は10日の延長を請求しています。どうしますか。
――(旧司法試験の口述過去問集で見覚えがある、難しい問いだから答えられなくてもいいはず)10日延長します。明文の根拠がないので。

でも、できないという明文の根拠もないですよね。
――(主査不満げ、この誘導に乗ろう)はい、できないという明文の根拠がないので3日延長すると考えを改めます(「撤回」という言葉を使わなくても伝わりますよね)。

わかりました。3日で捜査が終わりませんでした。検察官はどうしますか。
――(わからないけれどもとにかく何か言おう)3日で捜査が終わらなかったことを裁判官に伝えます。

伝えてどうするのですか。
――(方向性はあっているみたい、ということは)勾留の再度の延長を請求します。

裁判官は何日延長できますか。
――7日です。

なぜですか。
――最大で20日だからです。

20日というのは?
――(分けて説明しろということかな)最初にまず10日で、延長は10日までしかできないからです。

弁護人は被告人の身柄を早く解放したいと考えました。どうしますか。
――勾留の取消しを請求します…(主査は続きを待っているようだ。予備試験の口述過去問で似たような問いを見たような)準抗告をします。

準抗告は勾留全体にしませんよね。
――(主査はこれを待っていたのですね。しかも誘導してくれているのでこれに乗ろう)はい、勾留延長の決定に対してします。

検察官は、被害者Vの犯人を厳罰に処してほしいという供述書を証拠として提出しようとしています。このあとどうなりますか。
――被告人及び弁護人が異議があればあると言います。

その後どうなりますか。
――裁判所が証拠調べの決定をします。

先ほど異議と言ったのは、文字通りの異議という意味ですか。
――(あ、伝聞か)伝聞証拠の同意・不同意も述べます。

要は意見を言うということですね。ちなみに、これはどのような証拠になりますか。
――情状証拠です。

Aが同じような犯行を繰り返してきたという供述書があります。被告人と弁護人は同意をしたとします。裁判所はこれを証拠としてもよいでしょうか。
――(話がややこしくてついていけない)…伝聞証拠なので不同意と述べます。

ではなくて伝聞証拠の同意はしています。これを証拠にしてもよいでしょうか。
――はい、犯罪事実の成立を判断するために必要なので証拠調べをします。

犯罪事実の成立を判断するために必要ですか。
――常習窃盗で起訴されているのですよね。

いえ、起訴されているのは単純窃盗罪です。
――(余罪のことを聞いているのかな)それでしたら、顕著な特徴のある手口の場合は、犯罪事実の成立を判断するために必要だと考えます。

顕著な事実…Aは犯人性は認めているのですよ。
――その場合は、余罪を評価することになるので証拠とするのはまずいと考えます。

Aは被害者Vと示談をして、弁護人はそれを書面にしました。これはどういう証拠になりますか。
――(「余罪」という言葉が出たらさっきの問いはクリアなのかな)情状証拠です。

もっと言うとどういう証拠ですか。
――犯情です。

犯情なのですけれども、どう評価されますか。
――実質的に被害を回復し、反省していることがわかります。

それは被告人側の事情ですよね。被害者側の事情は?
――処罰感情が低下していることが示されます。

Aは示談を成立させてくれた国選弁護士に謝礼を支払おうとしました。これに問題はありますか。
――はい、問題があると考えます。

どのような問題ですか。
――国選弁護士は定められた枠内で活動するので、それはまずいです。

それは明文の定めがありますか。
――明文、明文…あったかと記憶しております。

弁護士職務基本規程ではないですか。
――(そこまで言ってくれるのですか)それです。

では、Aが別件の債務整理をその国選弁護人に依頼することに問題はあるでしょうか。
――はい、問題があると考えます。

なぜですか。
――先ほどの潜脱になるかと。

どういうことですか。
――(主査が微妙に納得してくれたようだったのにまだ聞くのですか)国選弁護人は決められた枠内で活動することが想定されているので…

お疲れさまでした。
――ありがとうございました。

 

誘導に乗れたかなという感触はあります。希望を込めて60点だと予想します。

 



LibreOffice Calcのマクロで仕訳帳から総勘定元帳を作成する

やりたいことはタイトルの通りです。凝りだしていろいろな機能を追加したら記事が長くなってしまいました。

結論だけが欲しい方は以下のファイルをダウンロードしてご利用ください。

journal2ledger.ods

できるだけわかりやすく記述したつもりですから、このファイル内のマクロだけを読んでもある程度理解できると思います。

デザインには頓着せず、ロジックだけを記載しています。

以下で理屈を説明しますので、改良やデザインの調整などご自由にしてください。

1.はじめに

個人事業や小さい法人では、専用の会計ソフトを使わずにエクセル等のスプレッドシートで会計管理をすることが多いと思います。

青色申告をするためには複式簿記により仕訳帳を日々つけることになります。そしてその仕訳帳をもとにして、総勘定元帳に転記し、試算表にまとめて、損益計算書と貸借対照表を作成するという流れになります。

仕訳帳から総勘定元帳への転記をLibreOffice Calcのマクロで自動化しようというのがこの記事の趣旨です。

エクセルだと会計ソフト不要!?エクセルを使って総勘定元帳(帳簿)を作るコピペ可!Excelマクロによる総勘定元帳作成 | 公務員×不動産投資の記事がヒットしましたが、私が調べた限りLibreOffice Calcでは見つからなかったので、自分で作ったという次第です。

2.試算表

上記のエクセルを使う場合の記事にも書かれていますように、試算表を作るほうが簡単です。マクロを使わずに関数だけで実現できます。ここでも先に試算表の説明をします。

下図のような仕訳帳があるとします。

そこから以下ような試算表を作りたいということです。

(1)借方合計と貸方合計

借方合計と貸方合計の列に入力する関数を、D3セルについて考えます。

A列に入力されている勘定科目に一致する金額を合計するので、sumif関数を使います。大ざっぱには以下のような感じです。

=SUMIF(仕訳帳.D2:D10000, A3, 仕訳帳.E2:E10000)

仕訳帳に入力されているデータを全部集計するだけならこれでもよいです。私は開始行と終了行を指定して範囲を区切って集計したかったので、sumif関数の範囲指定にoffset関数を使いました。

「仕訳帳.D2:D10000」の部分を「OFFSET(仕訳帳.D1, K1-1, 0, K2-K1+1, 1)」と書き換えました。仕訳帳シートのD1セルを基準にして、開始行−1だけ下がったセルを範囲の開始にして、終了行−開始行+1で範囲として選択すべき行数を算出し、1列を範囲にするという式です。「仕訳帳.E2:E10000」の部分も同様に書き換えます。

=SUMIF(OFFSET(仕訳帳.D1, K1-1, 0, K2-K1+1, 1), A3, OFFSET(仕訳帳.E1, K1-1, 0, K2-K1+1, 1))

行方向にドラッグできるように必要な部分を$マークで固定します(仕訳帳の列は2行おきになっているので列方向にはドラッグできません)。

=SUMIF(OFFSET(仕訳帳.D$1, K$1-1, 0, K$2-K$1+1, 1), A3, OFFSET(仕訳帳.E$1, K$1-1, 0, K$2-K$1+1, 1))

これを行方向にドラッグすれば借方合計のD列は完成です。

貸方合計のE列はE3セルに次のように入力して、行方向にドラッグします。

=SUMIF(OFFSET(仕訳帳.F$1, K$1-1, 0, K$2-K$1+1, 1), A3, OFFSET(仕訳帳.G$1, K$1-1, 0, K$2-K$1+1, 1))

(2)期首残高

期首残高は、仕訳帳の最初のデータ行を開始行とみなし、指定した開始行の1つ前の行を終了行と考えて、借方合計から貸方合計を引くことにより求めます。C3セルについて考えます。

その借方合計は次の式で求めることができます。

=SUMIF(OFFSET(仕訳帳.D$1, 1, 0, K$1-2, 1), A3, OFFSET(仕訳帳.E$1, 1, 0, K$1-2, 1))

貸方合計も同じように考えて、引き算をするのは次の式になります。

=SUMIF(OFFSET(仕訳帳.D$1, 1, 0, K$1-2, 1), A3, OFFSET(仕訳帳.E$1, 1, 0, K$1-2, 1))-SUMIF(OFFSET(仕訳帳.F$1, 1, 0, K$1-2, 1), A3, OFFSET(仕訳帳.G$1, 1, 0, K$1-2, 1))

これでほぼ完成なのですが、開始行として仕訳帳の最初のデータ行を指定するとエラーになります。そこでその判定をif関数でします。

=IF(K$1=2, 0, SUMIF(OFFSET(仕訳帳.D$1, 1, 0, K$1-2, 1), A3, OFFSET(仕訳帳.E$1, 1, 0, K$1-2, 1))-SUMIF(OFFSET(仕訳帳.F$1, 1, 0, K$1-2, 1), A3, OFFSET(仕訳帳.G$1, 1, 0, K$1-2, 1)))

行方向にドラッグすればC列の期首残高は完成です。

(3)調整後残高と期末残高

まずはF列の調整前残高を単純に借方合計から貸方合計を引いて計算します。

=D3-E3

これだと貸方の金額のほうが大きくなると残高がマイナスになるので、通例貸方に登場する勘定科目はB列に-1を入力して調整します。通例借方に登場する勘定科目は1を入力します。

G列の調整後残高は調整前残高にB列の借方貸方符号をかけます。

=F3*B3

H列の期末残高は、期首残高に調整前残高を加えます。

=C3+F3

F列からH列はそのまま行方向にドラッグすればよいです。

(4)合計確認

1行目に合計を用意して数字が合っているかを確認することをおすすめします。

=SUM(C3:C500)

例えばC1セルに上のように入力して列方向にドラッグします。

C列の期首残高とF列の調整前残高とH列の期末残高の合計はそれぞれ0になるはずですし、D列の借方合計とE列の貸方合計は同じ数字になるはずです。

 

3.仕訳帳で用いられている全勘定科目の書き出し

試算表のA列には仕訳帳で用いる全勘定科目を入力します。手作業で入力してもよいのですが、せっかくなので仕訳帳で用いられている全勘定科目を自動で取得するマクロを作りました。

そのためのsubプロシージャの本体はこれです。

'subプロシージャをまたいで使う変数の宣言
Dim TmpSheet As Object

'仕訳帳で用いられている全勘定科目の一覧を「試算表」シートのL列に書き出す
Sub WriteAllAccounts
    '「勘定科目一覧」一時シートを作成し、TmpSheet変数に格納する…(1)
    TmpSheet = CreateTmpSheet

    '仕訳シートの借方と貸方の勘定科目を全部「勘定科目一覧」一時シートのA列にコピーする…(2)
    CopyAllAccounts

    '「勘定科目一覧」一時シートにフィルターを適用して重複を非表示にする…(3)
    FilterAccounts

    '重複が非表示になっている「勘定科目一覧」一時シートのA列を「試算表」シートのL列にコピーする…(4)
    CopyAllDistinctAccounts

    '「勘定科目一覧」一時シートを削除
    If ThisComponent.Sheets.hasByName("勘定科目一覧") Then
        ThisComponent.Sheets.removeByName("勘定科目一覧")
    Endif
End Sub

TmpSheetはsubプロシージャをまたいで使われます。(1)〜(4)は独自に作成した関数やプロシージャです。順番に説明します。

(1)「勘定科目一覧」一時シートを作成し、TmpSheet変数に格納する

'「勘定科目一覧」一時シートを作成して返す
Function CreateTmpSheet() As Object
    With ThisComponent.Sheets
        'すでに「勘定科目一覧」シートがあれば削除する
        If .hasByName("勘定科目一覧") Then
            .removeByName("勘定科目一覧")
        Endif
        .insertNewByName("勘定科目一覧", 3)
        CreateTmpSheet = .getByName("勘定科目一覧")
    End With
End Function

何度も繰り返してThisComponent.Sheetsと書くのは面倒なので、Withブロックで囲んでいます。

まっさらな「勘定科目一覧」シートを作りたいので、すでに「勘定科目一覧」シートがあれば削除します。

シートの扱い方はMacros/Basic/Calc/Sheets – The Document Foundation Wikiにまとまっています。

(2)仕訳シートの借方と貸方の勘定科目を全部「勘定科目一覧」一時シートのA列にコピーする

下図のような状態がここでの目標です。

'仕訳シートの借方と貸方の勘定科目を全部「勘定科目一覧」一時シートのA列にコピーする
Sub CopyAllAccounts
    '変数の設定
    Dim LastRow As Long
    Dim DebitAccounts As Object
    Dim CreditAccounts As Object

    '仕訳シートの借方と貸方の勘定科目を全部「勘定科目一覧」一時シートのA列にコピーする
    JournalSheet = ThisComponent.Sheets.getByName("仕訳帳")
    LastRow = GetLastRow(JournalSheet)
    DebitAccounts = JournalSheet.getCellRangeByPosition(3, 1, 3, LastRow-1)
    CreditAccounts = JournalSheet.getCellRangeByPosition(5, 1, 5, LastRow-1)
    TmpSheet.copyRange(TmpSheet.getCellByPosition(0, 0).CellAddress, DebitAccounts.RangeAddress)
    TmpSheet.copyRange(TmpSheet.getCellByPosition(0, LastRow-1).CellAddress, CreditAccounts.RangeAddress)
End Sub

そのシートでデータが入力されている最終行を取得するという操作は頻繁につかうので、GetLastRowという関数を作りました。

'そのシートでデータが入力されている最後の行を返す
Function GetLastRow(Sheet As Object) As Long
    '変数の宣言
    Dim Cell As Object
    Dim Cursor As Object

    '最終行の取得(https://wiki.documentfoundation.org/Macros/Basic/Calc/Ranges#Cursors)
    Cell = Sheet.getCellRangeByName("A1")
    Cursor = Sheet.createCursorByRange(Cell)
    Cursor.gotoEnd()
    GetLastRow = cursor.RangeAddress.EndRow + 1
End Function

対象シートのA1セルにカーソルを置き、カーソルを下に進めて最終行を算出しています。Macros/Basic/Calc/Ranges – The Document Foundation Wikiを参考にしました。

CopyAllAccountsプロシージャに戻って説明を続けますと、仕訳帳の借方科目と貸方科目の範囲をそれぞれコピーし、それを全部「勘定科目一覧」一時シートのA列にコピーしています。セル範囲の操作はMacros/Basic/Calc/Ranges – The Document Foundation Wikiにまとまっています。

(3)「勘定科目一覧」一時シートにフィルターを適用して重複を非表示にする

先ほどの状態から空白でない値で重複を無視するという標準フィルターを適用します。そうすると下図のようになります。

'「勘定科目一覧」一時シートにフィルターを適用して重複を非表示にする(https://wiki.documentfoundation.org/Macros/Calc/ba026)
Sub FilterAccounts
    '変数の設定
    Dim FilterDesc As Object
    Dim Fields(0) As New com.sun.star.sheet.TableFilterField

    FilterDesc = TmpSheet.createFilterDescriptor(True) 
    With Fields(0)
        .Field = 0
        .Operator = com.sun.star.sheet.FilterOperator.NOT_EMPTY
    End With

    FilterDesc.setFilterFields(Fields())
    FilterDesc.SkipDuplicates = True
    TmpSheet.filter(FilterDesc)
End Sub

ほぼCreate Standard Filter – The Document Foundation Wikiそのままです。LibreOffice Calcでuniq(重複行を削除)する | Days of speedのように標準フィルターを適用するという作業をマクロ化しています。

(4)重複が非表示になっている「勘定科目一覧」一時シートのA列を「試算表」シートのL列にコピーする

'重複が非表示になっている「勘定科目一覧」一時シートのA列を「試算表」シートのL列にコピーする
Sub CopyAllDistinctAccounts
    '変数の設定
    Dim TrialBalanceSheet As Object
    Dim LastRow As Long
    Dim AllDistinctAccounts As Object

    '重複が非表示になっている「勘定科目一覧」一時シートのA列を「試算表」シートのL列にコピーする
    LastRow = GetLastRow(TmpSheet)
    AllDistinctAccounts = TmpSheet.getCellRangeByPosition(0, 0, 0, LastRow-1)
    TrialBalanceSheet = ThisComponent.Sheets.getByName("試算表")
    TrialBalanceSheet.getColumns.removeByIndex(11,1)
    TrialBalanceSheet.copyRange(TrialBalanceSheet.getCellRangeByName("L3").CellAddress, AllDistinctAccounts.RangeAddress)
End Sub

TrialBalanceSheet.getColumns.removeByIndex(11,1)でL列を削除してから、TrialBalanceSheet.copyRange(TrialBalanceSheet.getCellRangeByName(“L3”).CellAddress, AllDistinctAccounts.RangeAddress)でL3セルを起点にして貼り付けています。

4.総勘定元帳の作成

いよいよここからが本番です。総勘定元帳を作成する本体となるsubプロシージャです。

'subプロシージャをまたいで使う変数の宣言
Dim JournalSheet As Object

'総勘定元帳を作成する
Sub CreateGeneralLedger
    '変数の宣言
    Dim StartRow As Long
    Dim EndRow As Long

    '変数の設定
    JournalSheet = ThisComponent.Sheets.getByName("仕訳帳")
    StartRow = JournalSheet.getCellRangeByName("K1").value
    EndRow = JournalSheet.getCellRangeByName("K2").value

    '不要なシートを削除する…(1)
    DeleteUnnecessarySheets

    '仕訳シートの各行を総勘定元帳に転記する…(2)
    WriteLedgers(StartRow, EndRow)

    '総勘定元帳シートを試算表の並び順にソートする…(3)
    SortSheets
End Sub

JournalSheet変数はsubプロシージャをまたいで使われます。仕訳帳シートのK1セルとK2セルに記入された開始行と終了行を読み取り、(1)〜(3)を実行します。

(1)不要なシートを削除する

すでに総勘定元帳シートなどがあればそれを削除します。必要なシートは「仕訳帳」、「試算表」、「元帳ブランク」の3つだけです。

'不要なシート(仕訳・試算表・元帳ブランク以外のシート)を削除する
Sub DeleteUnnecessarySheets
    Dim i As Long
    Dim SheetName As String
    For i = ThisComponent.Sheets.Count - 1 To 0 Step -1
        SheetName = ThisComponent.Sheets.getByIndex(i).Name
        If SheetName <> "仕訳帳" And SheetName <> "試算表" And SheetName <> "元帳ブランク" Then
            ThisComponent.Sheets.removeByName(SheetName)
        End If
    Next
End Sub

インデックス(ブック内のシートの位置)でシートを指定しています。シートを削除するとインデックスが繰り上がってしまうので、繰り上がりが発生してもすべてのシートを走査できるように逆順でループを回しています。

(2)仕訳シートの各行を総勘定元帳に転記する

ここが最大の山場です。

'仕訳シートの各行を総勘定元帳に転記する
Sub WriteLedgers(StartRow As Long, EndRow As Long)
    '変数の宣言
    Dim i As Long
    Dim TransactionDate As Date
    Dim Debit As String
    Dim DebitAmount As Currency
    Dim Credit As String
    Dim CreditAmount As Currency
    Dim Summary As String

    For i = StartRow To EndRow
        '各行について必要な変数データの設定

        '分離して入力されている年・月・日を組み立ててDate型のTransactionDate変数に格納する…①
        TransactionDate = GetTransactionDate(i)

        With JournalSheet
            '年月日一体型の日付を仕訳帳のC列に入れる場合は「TransactionDate = GetTransactionDate(i)」をコメントアウトして代わりに下の行をコメントイン
            'TransactionDate = .getCellByPosition(2, i-1).value
            Debit = .getCellByPosition(3, i-1).String
            DebitAmount = .getCellByPosition(4, i-1).value
            Credit = .getCellByPosition(5, i-1).String
            CreditAmount = .getCellByPosition(6, i-1).value
            Summary = .getCellByPosition(7, i-1).String
        End With

        '借方の勘定科目に対応する総勘定元帳シートがなければ作成する…②
        CreateLedgerSheetIfNotExists(Debit)

        '借方の勘定科目を総勘定元帳に転記する…③
        Transcribe(TransactionDate, Debit, DebitAmount, Credit, Summary, True)

        '貸方の勘定科目に対応する総勘定元帳シートがなければ作成する…②
        CreateLedgerSheetIfNotExists(Credit)

        '貸方の勘定科目を総勘定元帳に転記する…③
        Transcribe(TransactionDate, Credit, CreditAmount, Debit, Summary, False)
    Next
End Sub

仕訳帳の各行のデータを読み込み、借方、貸方の順番で処理していきます。年月日一体型の日付を仕訳帳のC列に入れる場合は①を考えなくてすみます。

①分離して入力されている年・月・日を組み立ててdate型のTransactionDate変数に格納する

最初から仕訳帳にDate型で入力していれば単に入力値を取得するだけでよかったのですが、会計ソフトのように年・月・日を分離して記載したかったのでこの処理を考えました。

'分離して入力されている年・月・日を組み立ててDate型で返す
Function GetTransactionDate(i As Long) As Date
    '変数の宣言
    Dim TransactionYear As Long
    Dim TransactionMonth As Long
    Dim TransactionDay As Long

    '年・月・日を取得してDate型にして返す
    TransactionYear = GetValueOfThisCellOrUpperCell(i, 0)
    TransactionMonth = GetValueOfThisCellOrUpperCell(i, 1)
    TransactionDay = GetValueOfThisCellOrUpperCell(i, 2)
    GetTransactionDate = DateSerial(TransactionYear, TransactionMonth, TransactionDay)
End Function

年・月・日をそれぞれ取得して、DateSerial関数でDate型にします。

年・月・日は、そのセルに値が入っていればその値を、そうでなければ直近の上の行の値を取得します。

'仕訳帳の日付の書き方から、空白の場合は上にさかのぼって年・月・日の数字を取得する
Function GetValueOfThisCellOrUpperCell(i As Long, column As Long) As Long
    '変数の宣言
    Dim TargetCellValue As Long

    'そのセルの値を取得し、0でなければその値を返し、0なら再帰的にこの関数を適用する
    TargetCellValue = JournalSheet.getCellByPosition(column, i-1).value
    If TargetCellValue <> 0 Then
        GetValueOfThisCellOrUpperCell = TargetCellValue
    Else
        GetValueOfThisCellOrUpperCell = GetValueOfThisCellOrUpperCell(i-1, column)
    Endif
End Function
②借方または貸方の勘定科目に対応する総勘定元帳シートがなければ作成する
'その勘定科目名のシートが存在しなければ「元帳ブランク」シートをコピーすることにより作成し、A1セルにその勘定科目名を記入する
Sub CreateLedgerSheetIfNotExists(SheetName As String)
    If Not ThisComponent.Sheets.hasByName(SheetName) Then
        ThisComponent.Sheets.copyByName("元帳ブランク", SheetName, 3)
        ThisComponent.Sheets.getByName(SheetName).getCellRangeByName("A1").string = SheetName
    Endif
End Sub

見たままのコードかなと思います。

元帳ブランクシートのE3の期首残高セルには「=VLOOKUP(A1, $試算表.A3:C500, 3, 0)」という関数を仕込んであります。その元帳ブランクをコピーして作成した総勘定元帳の勘定科目シート名をA1セルに記入することでその勘定科目の期首残高を試算表から取得するという仕組みです。

また、元帳ブランクシートのA列は日付形式に、C列からE列はカンマ桁区切りの数値形式にセルの書式設定をしてあります。

③借方または貸方の勘定科目を総勘定元帳に転記する
'借方または貸方を総勘定元帳に転記する
Sub Transcribe(TransactionDate As Date, Account As String, Amount As Long, CorrespondingAccount As String, Summary As string, DebitFlag As Boolean)
    '変数の宣言
    Dim LedgerSheet As Object
    Dim LastRow As Long

    '変数の設定
    LedgerSheet = ThisComponent.Sheets.getByName(Account)
    LastRow = GetLastRow(LedgerSheet)

    '取引日、相手科目、金額、残高、摘要の記入
    With LedgerSheet
        .getCellByPosition(0, LastRow).value = TransactionDate
        .getCellByPosition(1, LastRow).string = CorrespondingAccount
        '金額の入力欄と残高の計算式は借方かどうかで条件分岐
        If DebitFlag Then
            .getCellByPosition(2, LastRow).value = Amount
            .getCellByPosition(4, LastRow).value = .getCellByPosition(4, LastRow-1).value + Amount
        Else
            .getCellByPosition(3, LastRow).value = Amount
            .getCellByPosition(4, LastRow).value = .getCellByPosition(4, LastRow-1).value - Amount
        Endif
        .getCellByPosition(5, LastRow).string = Summary
    End With
End Sub

取引日、勘定科目、金額、相手科目、摘要、借方フラグを引数に取っています。

取引日、相手科目、金額、残高、摘要のそれぞれを適切な箇所に転記しています。

(3)総勘定元帳シートを試算表の並び順にソートする

試算表は慣行や必要性に従って並び順を整理することになるでしょうから、総勘定元帳もその順番でソートします。

'総勘定元帳シートを試算表の並び順にソートする
Sub SortSheets
    '変数の宣言
    Dim i As Long
    Dim TrialBalanceSheet As Object
    Dim LastRow As Long
    Dim Account As String

    '変数の設定
    TrialBalanceSheet = ThisComponent.Sheets.getByName("試算表")
    LastRow = GetLastRow(TrialBalanceSheet)

    '試算表シートのA列の3行目から勘定科目を順に読み込み、その勘定科目名のシートがあれば末尾に移動させる
    For i = 3 To LastRow
        With ThisComponent.Sheets
            Account = TrialBalanceSheet.getCellByPosition(0, i-1).string
            If .hasByName(Account) Then
                .moveByName(Account, .count)
            End If
        End With
    Next
End Sub

少しややこしいですが、これも見たままかなと思います。

5.思考プロセスその他細かいことなど

最初は「Option VBASupport 1」を設定してエクセルのVBA互換で作ろうかなとも思ったのですが、何が互換していて何が互換していないとかを考えるのが面倒だったので、どうせなら自分で一から作ろうと決意しました。

LibreOffice固有のマクロを作るとして、basicにするかpythonにするかも少し悩みました。しかしマクロでpythonを使うための資料が少なく、環境構築も面倒そうだったので、basicにしました。pythonを使うのであれば、マクロではなく、pythonをベースにしてデータを読み込んで処理する形にするほうが見通しがよいでしょう。

「Option Explicit」を設定して変数は宣言するようにしています。String, Long, Date, Objectという分類で型指定もしています。

わかりやすさのために、関数やsubプロシージャは細かく切り出しています。戻り値が必要な場合は関数を、そうではなく処理をするだけの場合はsubプロシージャを使っています。

関数や変数の命名についてもわかりやすさを重視して長い名前を付けました。

手元の環境で数百件の仕訳データから総勘定元帳を作成すると数十秒かかりました。これくらいなら許容範囲ですから、速度のことを特に意識はしていません。年月日一体型の日付を仕訳帳に入力するようにすれば処理が減って時間が短縮されます。

不要なシートを削除するDeleteUnnecessarySheetsプロシージャを作る際に、ループを前から順番に回して削除されるシートと削除されないシートが出てきたことに悩みました。オブジェクトのディープコピーをして解決する方向も探りましたが難しそうだったので断念し、ループを逆順で回すという解決に落ち着きました。

これだけを作るのに何日もかかりました。いろいろ検索して調べようとしても資料が少なかったです。本もほとんどなさそうですし。この記事中でも示した公式ドキュメントも貧弱で、試行錯誤を繰り返しました。

 



LPIC-1に合格しました

LPIC-1に合格しました。

どちらもできたという手応えはあったのですが、結構ぎりぎりですね…

 

1年ほど前から漠然とLPICを意識するようになり、LPIC受験までに乱読した本たちを読んだりしました。

 

1か月ほど前に具体的な受験予定を決めてからしたことは以下になります。

 

まず、LPI Learning Materialsをもう一度読みました。何と言ってもこれは公式筋の学習教材ですし、質が高いので、最優先になるでしょう。Essentialsから読むことをおすすめします。日本語訳は現状101の途中までしかありません。

 

次に、Ping-tを一通りやりました。WEB問題集とコマ問の両方を少なくとも1周はしました。

 

俗に言うあずき本、白本、黒本もこの順で全部読みました。最初に解説がまとまっているあずき本を読んでいけるかもと思い、白本で撃沈し、黒本で自信を回復するという順番になりました。


LPICレベル1 : Linux技術者認定試験学習書


作 者: 中島能和 著,濱野賢一朗 監修

出版社: 翔泳社

発売日: 2015年06月26日


LPICレベル1スピードマスター問題集 : Linux技術者認定試験学習書


作 者: 山本道子, 大竹龍史 著

出版社: 翔泳社

発売日: 2015年11月19日


LPIC Level1問題集 : LPI Level1 Exam 101 LPI Level1 Exam 102


作 者: 鳥谷部昭寛, 菖蒲淳司 著,ソキウス・ジャパン 編

出版社: インプレス

発売日: 2015年12月17日

 

私はケチって少し前のバージョンの本を入手しました。概ね内容は合っていたものの、やはり現在の試験範囲とは少し違うと感じる部分はありました。お金に余裕があるなら最新版にしたほうがよいです。

 

自分の環境でコマンドを打ち込んで確認したり、○○と△△ってどう違うんだろうと検索して調べたりした知識は定着がよく、試験でも答えやすかったです。

 

大量にインプットしてキーワードや機能の存在を知る→自分の環境で試したり調べたりして深く理解する→直前にコマンドのオプションの種類などを記憶の片隅に詰め込む、という流れがいいかなと思っています。

 

それと、試験時間は余りがちですから、見直しを慎重にすることをおすすめします。

 

LPIC-1の受験をきっかけにしてlinuxをよりスムーズに使えるようになり自信がついたのはよかったです。



LPIC受験までに乱読した本たち

私は10年ほどlinuxを使ってきました。といってもGUIベースのubuntu系なので、ごく基本的なコマンドしか使っていませんでした。

最近はdocker等のクラウドを使うことが多くなり、ちょっとしたシェルスクリプトを書くことが多くなりました。

そこで、この際にLPICを受験してlinuxの基礎を固めようと決意しました。

受験日を決めるまでに乱読した本たちを紹介します。

 

1.入門的な本

(1)入門者のLinux : 素朴な疑問を解消しながら学ぶ


入門者のLinux : 素朴な疑問を解消しながら学ぶ


作 者: 奈佐原顕郎 著

出版社: 講談社

発売日: 2016年11月11日

実践的な形でlinuxに触れられるのがよいです。著者の情熱が伝わってきます。linuxを使うと何ができるか、どうよいのかが何となくわかる本なので、最初の一冊としておすすめします。

 

(2)新しいLinuxの教科書


新しいLinuxの教科書


作 者: 三宅英明, 大角祐介 著

出版社: SBクリエイティブ

発売日: 2015年11月02日

その名の通り教科書的な内容です。すでにlinuxを学ぼうとするモチベーションがあるならこの本から入るのがよいです。

 

(3)Linux標準教科書





作 者: 

出版社: 

発売日: 1970年01月01日

Linux標準教科書 ダウンロード LinuCレベル1対応 | Linux技術者認定試験 リナック | LPI-Japanから無料で手に入れることができるので、気軽に読むことができます。サーバー構築やセキュリティなどの上位版も無料で読めるのでありがたいです。

 

(4)UNIXシェルスクリプトコマンドブック


UNIXシェルスクリプトコマンドブック


作 者: 山下哲典 著

出版社: SBクリエイティブ

発売日: 2015年10月27日

(5)UNIXコマンドブック : UNIX Fedora,Ubuntu,Mac OS 10,FreeBSD,Solaris


UNIXコマンドブック : UNIX Fedora,Ubuntu,Mac OS 10,FreeBSD,Solaris


作 者: 田谷文彦, 三澤明 著

出版社: ソフトバンククリエイティブ

発売日: 2013年03月13日

短く項目が区切られているのでスキマ時間に読むには重宝します。

 

2.中井悦司さんの本

(1)プログラマのためのGoogle Cloud Platform入門 : サービスの全体像からクラウドネイティブアプリケーション構築まで


プログラマのためのGoogle Cloud Platform入門 : サービスの全体像からクラウドネイティブアプリケーション構築まで


作 者: 阿佐志保 著,中井悦司 著・監修

出版社: 翔泳社

発売日: 2017年08月02日

私が初めて出会った中井悦司さんの本はこれです。GCPを学ぶ必要性に駆られて手に取りました。GCPとは直接関係のない教養的な内容があったのが、私にとっては魅力的でした。

 

(2)プロのためのLinuxシステム構築・運用技術


プロのためのLinuxシステム構築・運用技術 : システム構築運用/ネットワーク・ストレージ管理の秘訣がわかる : キックスタートによる自動インストール、運用プロセスの理解、SAN/iSCSI、L2/L3スイッチ、VLAN,Linuxカーネル、systemd、ファイルシステム、問題判別ノウハウ、プロとしてのLinux技術


作 者: 中井悦司 著

出版社: 技術評論社

発売日: 2016年10月06日

著者から芋づる式にたどって次に読んだのがこれです。同著者の本の中では比較的新しいです。初心者レベルではなく、LPIC-2よりも高度かなと感じます。

 

(3)プロのためのLinuxシステム・10年効く技術 : シェルスクリプトを書き,ソースコードを読み,自在にシステムを作る


プロのためのLinuxシステム・10年効く技術 : シェルスクリプトを書き,ソースコードを読み,自在にシステムを作る


作 者: 中井悦司 著

出版社: 技術評論社

発売日: 2012年09月25日

10年くらい前の古い本です。技術というか考え方は10年後の今でも効きますね。

 

(4)「独習Linux専科」サーバ構築/運用/管理 : あなたに伝えたい技と知恵と鉄則


「独習Linux専科」サーバ構築/運用/管理 : あなたに伝えたい技と知恵と鉄則


作 者: 中井悦司 著

出版社: 技術評論社

発売日: 2013年09月18日

中井悦司さんの本の中では一番入門的で教科書的だと思います。

 

(5)プロのためのLinuxシステム・ネットワーク管理技術


プロのためのLinuxシステム・ネットワーク管理技術 : ネットワーク・インフラ構築,セキュリティ管理,仮想化技術の極意がわかる : セキュリティ管理,iptables,OpenLDAP,Kerberos,KVM仮想化環境,プロとしてのLinuxネットワーク管理技術 : Red Hat Enterprise Linux対応


作 者: 中井悦司 著

出版社: 技術評論社

発売日: 2011年06月01日

かなり細かい内容に入り込んでいるので、プロのためのLinuxシステム・ネットワ-ク管理技術 / 中井 悦司【著】 – 紀伊國屋書店ウェブストア|オンライン書店|本、雑誌の通販、電子書籍ストアで目次を見て必要だと感じる人が読めばいいかなと思いました。

 

(6)Docker実践入門 : Linuxコンテナ技術の基礎から応用まで : Docker Hub、Dockerfile、Kubernetes、Atomic Host


Docker実践入門 : Linuxコンテナ技術の基礎から応用まで : Docker Hub、Dockerfile、Kubernetes、Atomic Host


作 者: 中井悦司 著

出版社: 技術評論社

発売日: 2015年11月12日

dockerを使っていてlinuxを学ぶ必要を感じた私のような人にはぴったりの本です。

 

3.オライリー本

(1)入門bash : bash 2.05b & 3.0対応


入門bash : bash 2.05b & 3.0対応


作 者: Cameron Newham, Bill Rosenblatt 著,クイープ 訳

出版社: オライリー・ジャパン

発売日: 2005年12月07日

オライリー本が好きな人には間違いなくおすすめします。

 

(2)詳解シェルスクリプト


詳解シェルスクリプト


作 者: Arnold Robbins, Nelson H.F.Beebe 著,日向あおい 訳

出版社: オライリー・ジャパン

発売日: 2015年10月27日

こちらもオライリー本らしさが発揮されています。上の入門bashより難しく感じました。

 

4.番外編

UNIXという考え方 : その設計思想と哲学


UNIXという考え方 : その設計思想と哲学


作 者: Mike Gancarz 著,芳尾桂 監訳

出版社: オーム社

発売日: 2001年07月30日

これを読むとlinuxの背後にある思想がわかるかもしれません。古い本ではありますが、その点を割り引いても読んでいておもしろいです。

 




top