Dreamforce 2012に参加したよ - 1日目 -
突然ですが、Dreamforce2012に参加してきました。
実はSan Franciscoに来るのは10数年ぶりでして、当時の記憶は幾分残ってましたが、泊まったホテルとかは思い出せず。。ちなみに、初めて1人旅したのがSan Franciscoだったので、勝手に感慨深く思ってましたw
それはさておき、Dreamforceは初参加でしたので、色々と圧倒されまくりな4日間でした。(あー疲れた...w)
(忘れないうちに)覚えている限りで所感を残しておこうと思います。
1日目 (9/18)
参加したセッションはこんな感じでした。
- Building Desktop & Mobile HTML5 Applications with Sencha and Force.com
- Apex Design Patterns
- Introduction to Force.com Canvas Apps
- Test Driven Development Fundamentals on Force.com
Building Desktop & Mobile HTML5 Applications with Sencha and Force.com
Javascript UI FrameworkであるSenchaを使って、Force.comと組み合わせて、いかにしてMobileアプリやらWebアプリを作りましょうか?といった話でした。
Salesforce.comでもSencha(というかExtJSといった方が良いかな?)は使われていて、開発者コンソールや、レポートビルダー等で見かけることができます。
その他、おそらくRemoteActionにも使われているのではないでしょうか?
自分もExtJSを使っておりまして...個人的には結構気に入ってます。
※ちなみに、ライセンス形態としては、商用版とオープンソース版の2種類が用意されています。
セッションの内容としては、このために書いた..と思われるブログが2つあって、それを見た方が早そうですのでご紹介します。
- Developing Mobile Applications with Force.com and Sencha Touch - Part 1 | Blog | Sencha
- Developing Mobile Applications with Force.com and Sencha Touch - Part 2 | Blog | Sencha
ちなみに、既に日本語訳までも!w(素晴らしいです)
- Force.comとSencha Touchを使ったモバイルアプリケーション開発 Part1 | 株式会社ゼノフィ
- Force.comとSencha Touchを使ったモバイルアプリケーション開発 Part2 | 株式会社ゼノフィ
個人的には、Part2 で取り上げられている "Step 8: Adjusting the Model and Adding a Data Proxy" が非常にタメになりました。
SalesforceでExtJS4を使ってみようか (1) - yonet77的な雑記帳にて、ExtJSからForce.comにデータを連携するProxyクラスを(頑張って)自作してましたが、"Step8"のやり方を勉強して、現在製作中のアプリをより良い方向に変えていきたいと思います。。
あと、発表して頂いた方に自分が作っている最中のアプリを紹介することができました。(I can't speak English.. なので、どこまで伝わったか疑問ですが。。)
汗かきながら説明している自分がなんだか滑稽でしたが、まぁせっかく来たんだし、と。
日本にもExtJSを使ってForce.com上でアプリ作っているヤツもいるんだゼ!と知らしめる(?)ことができて何よりでした。
Apex Design Patterns
GoFのデザインパターンをApexでやってみたよ!という類いの話です。
紹介したパターンはこんなところでした。
- Singleton
- Strategy
- Decorator
- Facade
- Composite
- Bulk State Transition(これは自作した...?)
ここでは、
- こんなところで問題が起きたよ
- このパターンを使えばいいんじゃない?
- コード書いてやってみよう!
という順番で各パターンを説明してました。
何を隠そう、デザインパターンは詳しくない(おい!)のですが、内容自体は割とよく見かける話でした。個人的にはCompositeパターンの例がなかなか面白かったです。
こんな感じにCompositeパターンを使った演算子の実装を紹介していました。
■実装
public interface Expression { Expression add(Expression expr); Expression set(String name, Boolean value); Boolean evaluate(); } public abstract class Composite implements Expression{ public List<Expression> children {get; private set;} public Composite(){ this.children = new List<Expression>(); } public Expression add(Expression expr){ children.add(expr); return this; } public Expression set(String name, Boolean value){ for(Expression expr : children) expr.set(name,value); return this; } public abstract Boolean evaluate(); public Boolean hasChildren{get{ return !children.isEmpty(); } } public class AndComposite extends Composite{ public override Boolean evaluate(){ for(Expression expr : children) if(!expr.evaluate()) return false; return true; } } public class OrComposite extends Composite{ public override Boolean evaluate(){ for(Expression expr : children) if(expr.evaluate()) return true; return false; } } public class Variable implements Expression{ public String name {get;private set;} public Boolean value {get;private set;} public Variable(String name){ this.name = name; } public Expression add(Expression expr){ return this; } public Expression set(String name, Boolean value){ if(this.name != null && this.name.equalsIgnoreCase(name)) this.value = value; return this; } public Boolean evaluate(){ return value; } }
■使用例:
//1 OR (2 AND 3) Expression expr = (new OrComposite()) .add(new Variable('1')) .add((new AndComposite()) .add(new Variable('2')) .add(new Variable('3')) ) .set('1',false) .set('2',true) .set('3',false); System.debug(expr.evaluate()); //FALSE OR (TRUE AND FALSE) => FALSE expr.set('3',true); System.debug(expr.evaluate()); //FALSE OR (TRUE AND TRUE) => TRUE
なるほどねーと思いました。そもそもの話で、GoFパターンをちゃんと理解しておかないとなーと常日頃思ってますので、引き続き精進しようと思います。。。
Introduction to Force.com Canvas Apps
このDreamforceで何度もデモを見させられたCanvas Appsの紹介でした。
New at Dreamforce 12: Force.com Canvasが参考になるのではないでしょうか。
すごーくざっくり言うと、"FacebookアプリのForce.com版"といった感じでしょうか。。
Canvasアプリを新たに作成するときには、テンプレートが用意されているので、それに従って作れば「あっ!」という間にHeroku上にCanvasアプリが作成されます。
既にあるものをForce.comに組み込むこともできるみたいです。
ここらへんの情報は色々出回っているので、既にご存知かと思いますが、最後に大事なポイントを。
Test Driven Development Fundamentals on Force.com
TDDの基礎...という感じでした。"on Force.com"とありますが、別にForce.comに限った話ではなく、割と一般的な話でした。とはいっても、非常に大事なテーマなので、どっかの誰かに聞かせてやりたい気持ちで一杯です。
大きなポイントとしては、
といった"黄金の回転"を回し続けていくことが大事なんだよ、ということを語ってくれていました。
セッションでは、この回転を途中まで紹介して、残りの回転は各自(以下を参考にして)やってみよう!という締めでした。
knthornt/Dreamforce-2012---TDD-Session · GitHub
最後に、質問セッションにて「TDDの中で、リファクタする最も良いタイミングはどう思いますか?」的な質問を投げてみました。
回答としては(多分)「テストがGreenになった後ならいつでもいいと思うし、自分で『このコード気持ち悪いな』と思ったらリファクタすべきじゃないかな」といった感じでした。(英語を全て聞き取れなかった... orz)
とにかく
マイクを手に取って、英語で質問する
ということを経験してみたかったので、内容はさておき、緊張感Maxの状態でやり遂げられて良かった...と思います。(すげー汗かきました...)
とまぁ、1日目としてはこんな感じでした。2日目以降はそのうち....
インストールしたパッケージをカスタマイズする上でハマったこと
Force.com上で開発していく上で、パッケージをカスタマイズしていくことも多々あるのではないでしょうか?
(当方、glovia OrderManagementをカスタマイズすることが多いですが...)
そんなパッケージのカスタマイズの中で、思わぬ出来事に遭遇しましたのでご紹介しようかと。
結論から先に言うと...
ということです。
※予期せぬ例外が発生することもあるので避けるべき、ということです。
具体例
準備
今回発生したケースの前提です。
- パッケージ管理内で、「Status__c」というAPI名がテキスト型として定義されている(実際には、xxx__Status__c というAPI名になります)
- 上記のオブジェクトにカスタム項目として「Status__c」を選択リスト型として追加する
パッケージ内のオブジェクトとしては、こんな項目が定義されたようになります。
- xxx__Status__c(テキスト型)
- Status__c(選択リスト型)
ここで、さらに入力規則 or 項目自動更新で、「Status__c」を数式に使ってみます。例えば
IF( TEXT ( Status__c ) = 'xxxx', 100, 0);
という感じの数式を埋め込んでみます。
※ココでは、新たに追加した選択リスト型のStatus__cを使う感じです。
例外発生!
項目自動更新が実行されると、こんなエラーが発生するようになりました。
このレコードを保存するとき、ワークフローまたは承認プロセスの項目自動更新によるエラーが発生しました。(中略)
関数 'TEXT()' のパラメータが間違っています。期待数字, 日付, DateTime, 選択リスト、受信テキスト
え?
関数 TEXT() は選択リスト型で使用しているのに、なぜこんなエラーがッ...!?
大まかに書くと、こんな感じの現象でしょうか。。
原因は?
管理パッケージ内のトリガが起動したとき、それに併せて入力規則(パッケージ管理外で定義された入力規則も含めて)が評価されると思います。
入力規則を評価する際に、パッケージ内のトリガで発生してきた場合にはパッケージ内の項目を優先的に参照するのではないでしょうか?
(ただ、標準のSalesforce画面からデータ操作した場合、エラーなく処理されることもあったりと良く分からない・・ところもあります。すみません。。。)
回避策は?
結局のところ、
パッケージ内で定義されているAPI名で項目を追加するのは避けましょう
に尽きると思います。
今回の例でいうと、
- パッケージ内では Status__c(テキスト)で定義されている。(外部からは xxx__Status__c)
- パッケージ外で Status__c(選択リスト)で定義する
ということは止めましょう、という話ですね。
ただ、上記の現象とは別に、類似した名称で定義するのは混乱の火種になりかねないので、名前付けは熟考しましょう、ということですね。
※当たり前すぎる話でオチもないですが・・(苦笑)
最後に
一応、Salesforceに問い合わせたところ、既知の不具合のようで将来的なリリースにて修正予定とのことでした。(時期は未定)
そんなわけで、しばらくは
類似したAPI名を使うのは避ける
という回避策で逃げましょう。
今回はパッケージをカスタマイズしていく上でハマったお話でした。
ではでは〜
Glovia Order Management (on Salesforce) を使ってみようか (10)
久々のgOMネタでも更新します。
本日のネタは開発者よりのネタです。
gOMをカスタマイズするならコレだけは知っとけ
的なネタです。
gOMで用意している機能をApexから利用する
gOMには様々な機能が定義されており、色んなところで使われてます。ざっと見渡しても、こんな機能が思い浮かぶのではないでしょうか?
- 受注残消し込み(いわゆる在庫引当)
- Quick梱包
- Quick出荷
- 出荷確認
- 請求書作成 ....etc
gOMをカスタマイズしながらも、gOM内で想定しているデータの流れに乗っかっていくには、これらの機能をApexから利用することは避けられ...ないでしょう。
というか、自前で作るのは超面倒ですし、gOMのアップグレードに伴って、いちいち修正していくのは...これまた現実的ではありません。。
というわけで、gOMで定義されている機能をApexから呼び出す方法についてご紹介しようと思います!gOMをカスタマイズしていく上で、知っておくと色々と便利かと思います(たぶん)。
※1 JoJo風に言えば、この辺りで、「ドギャーン!」とか擬態音を入れたいところですが、控えます。(ゴゴゴゴゴ..!!)
※2 このあたりはGlovia社の方にもご協力頂きました。多々感謝です!
gOMで定義している機能の利用方法
受注残消し込み
gii.inventoryReserve.clearBackorder(LIST<Id> inventoryReserveId);
- 第1引数: 処理対象となる在庫予約のIdのList
在庫予約
gii.inventoryReserve.reservation(LIST<Id> salesOrderLineId);
- 第1引数: 処理対象となる販売オーダラインのIdのList
Quick梱包
gii.inventoryPack.createPackList(LIST<Id> selectedRecordIds, String groupBy, String IvStatus, String calledFrom);
- 第1引数: 処理対象となる在庫予約のIdのList
- 第2引数: 集約単位(販売オーダ毎の場合、'SalesOrder' と指定 それ以外は知らない...)
- 第3引数: 'Reserved' を指定 それ以外は知らない...
- 第4引数: ''を指定 本来はコール元の画面等を指定するみたいだけど、ブランクでも可
梱包指示確認
gii.inventoryPack.confirmPackList(LIST<Id> selectedRecordIds);
- 第1引数: 処理対象となる梱包指示のIdのList
梱包指示キャンセル
gii.Cancellation.cancelPacklist(SET<Id> PackListId, String calledFrom);
- 第1引数: 処理対象となる梱包指示のIdのSet
- 第2引数: ''を指定 本来はコール元の画面等を指定するみたいだけど、ブランクでも可
出荷確認
gii.packListShipment.shipPackList(LIST<Id> selectedRecordIds, String groupByAndShippedDate, String calledFrom);
- 第1引数: 処理対象となる出荷指示のIdのList
- 第2引数: 集約単位(販売オーダ)と日付(出荷日)を指定 例)'SalesOrder;2012-08-20'
- 第3引数: ''を指定 本来はコール元の画面等を指定するみたいだけど、ブランクでも可
Quick出荷
gii.inventoryReserve.quickShip(LIST<Id> selectedRecordIds, String groupByandShippedDate);
- 第1引数: 処理対象となる在庫予約のIdのList
- 第2引数: 集約単位(販売オーダ)と日付(出荷日)を指定 例)'SalesOrder;2012-08-20'
請求書作成
gii.OrderInvoicing.createInvoice(LIST selectedRecordIds, String groupByandInvoiceDate);
- 第1引数: 処理対象となる請求書作成準備のIdのList
- 第2引数: 集約単位(販売オーダ or 取引先)と日付(請求日)を指定 例)'SalesOrder;2012-08-20', 'Account;2012-08-15'
補足です
上記に書いた内容は、自分がよく使っていた範囲の内容となります。パッと見た感じでは、「出庫」に関する機能もApexから利用できると思います。
調べた方法に関しては...泥臭いですが、gOMをインストールした環境で、Apexクラスを参照して自分で試してみたりしました。もちろん中身は参照できないので、名前だけで判断することになりますが。。(苦笑)
例えば、こんなところから「くさいなー」という雰囲気を感じたらテストコード書いて試してみたり...ですね。
そこから推測したりしながら、適当に試してみる感じです。。
※もちろん、この他にGlovia社に問い合わせることもしました。
最後に
ちなみに、先日Glovia社に伺ったところ、gOM内で定義している機能はAPIとして公開しようと考えているそうです。(時期までは分かりませんが)
そんなわけで、それが公開されたら、このエントリも不要となりますね。。(苦笑)
まぁ、そんな期間限定的なエントリということでした。
それではより楽しい(?)gOMカスタマイズを!
Force.com Developer Group Japan Meetup#2 に参加しました
気を抜いてしまった模様で、あっという間に8月です。
"8月病"にかからないよう(?)気をつけたいところですね。
さて、Force.com Developer Group JP Meetup#2に参加してきました。
今回はデジタルコーストさんにご協力頂いて、STARTUP Base Campにて開催しました!
このオフィスは非常にキレイで色々と便利なので、普段から使えるのは羨ましい限りです(笑)
今回も80人募集にて、実際には5,60人くらい来て頂けたんじゃないでしょうか。有り難いことです。
Force.comはまだまだ注目されているのではないか?と再確認できて良かったです。
発表内容
今回はGoogle Docsで資料を作りました。準備不足感がハンパなくて色々と反省です。。
内容自体は入れ子集合モデルをForce.com上で実現してみたよ、という内容です。
古くから考えられたものですので、内容自体は枯れてるけど、割とマニアックな概念かと思います。そして、Force.comの上でも十分実現できるよ、という紹介でした。
本来であれば、自己結合など、通常のSQLが書けるプラットフォームで実装した方が色々と便利なことも多いんですが、Force.com上でどこまでできるのか?という可能性を垣間見ることができたんじゃないでしょうか?
これからも引き続き、Force.comでの可能性について色々と検証していきたいと思います。
(ただし気が向いたときに限る...と思います)
そして、引き続き、次回は未定です。。
Force.com Developer Group Japan Meetup#1 に参加しました
Force.com Developer Group JP Meetup#1に参加してきました。
定員65名のところ、大半の方々に参加頂いて大変有り難く思っています。
そして、この人数を前にして最初の挨拶で30分程の枠を割り当てられるというのも人生初でした....
大変緊張して、途中妙なことを話したりしてたような気がしますし、参加者の方々の表情を確認するような余裕もありませんでしたが、とても良い経験をさせてもらいました!
もう少し場慣れしたりする必要があるなーと痛感しました。
あと、LTの発表内容が期待以上でスゴかった...自分の勉強不足を痛感しました。。(苦笑)
当日の様子は、ココから確認できます。ご参考までに...
- Force.com Developer Group JP Meetup #1 - Togetter
@a_kuratani: [URL] URL Developers Meetup #1 の個人的まとめ URL
発表内容
"Force.com"らしく(?)、このためにDeveloper Editionを1つ作成して、Visualforce Pageで作成しました。多分もうやらない。(苦笑)
Force.com Developer Group Japanについて...
僕が初回の挨拶で言いたかったことは概ね(一応)伝えられたかと思います。一番の思いとしては、
開発者が「会社」という枠組みから解放されて「いち開発者」として気兼ねなく参加する"Force.com Developer"コミュニティが欲しかった
ということに尽きるかな?と今は思っています。
今まではSalesforce.com主体でDevleoper向けのイベント等ありましたが、そこにはどうしても「企業に所属する開発者として...」という色が感じられました。
確かに自分も、とある企業に所属していますし、所属している会社の知名度が上がって仕事が増えるようになるために、そういったイベントでも活動していく必要はあるかと思います。
ただ、それとは別に開発者として、純粋にスキルを磨きたい、という思いも当然あるわけで、そういった思いをぶつけるコミュニティもあったらいいなぁ...という思いがたまたま実現できた、ということになります。
そんなわけで、"Force.com Developer"コミュニティを一緒に作ろう!と賛同してくれたメンバーには非常に感謝しております。
一応、"Force.com"というキーワードを残しつつ技術的に面白そうなネタを追っかけていきたいなーと思います。
※別に"Force.com"に限定しなくても、別のネタを"Force.com"ではどうやったら適用できるか!?なんてネタもアリだと思います。
そんな活動を地道に続けながら、Force.com Developer User Groupsにも掲載されるようになったり、他の勉強会で「"Force.com"の開発やってます....」と堂々と言えるようになったり(笑)したらいーなー...と思います。
千里の道も一歩から
という言葉もありますし、地道に途切れることなく(そして過度な無理もせずに)活動を続けて行きたいと思います。
Force.comでのJSON Support -ApexコントローラのRemoteActionを添えて-(その後)
以前、Force.comでのJSON Support - yonet77的な雑記帳にて、管理パッケージ内にあるカスタムオブジェクトの日付項目をJSON.deserializeできない...ということを書きました。
うん、もう覚えてないよねw
ことの発端は、Summer '12 になった直後に、JSON.deserialize の挙動がおかしくなったことでした。
@yonet77: Type t = Type.forName('List<Account>'); ってやると "System.UnexpectedException: Salesforce System Error:" って怒られるよ。。前のバージョンでは動いたのに... #forcedotcom
でも、その1週間後くらいには直ってたので、ヨカッタヨカッタと思ったところで、もう1つふと思い出しました。
そう、管理パッケージ内のカスタムオブジェクトの日付項目を含めてJSON.deserializeするとエラーになってた件です。
↓
FATAL_ERROR System.JSONException: Cannot deserialize instance of date from VALUE_STRING value 2011-12-30
今回の修正で、挙動が変わったかもしれないッ・・・!
ということで、レッツトライ。
こんなコードを走らせてみました。
Type objType = Type.forName('gii__SalesOrder__c'); String paramString = '{"gii__RequiredDate__c":"2011-12-30", "gii__Released__c":true, "Phase__c":"ご来店", "Remarks__c":"ABCDEFGHIJKLMN,4444aaa"}'; gii__SalesOrder__c testSO = (gii__SalesOrder__c)JSON.deserialize(paramString, objType); System.debug('** testSO : ' + testSO);
↓
14:21:46.132 (14132484000)|USER_DEBUG|[172]|DEBUG|** testSO : gii__SalesOrder__c:{gii__RequiredDate__c=2011-12-30 00:00:00, Remarks__c=ABCDEFGHIJKLMN,4444aaa, Phase__c=ご来店, gii__Released__c=true}
おや・・?なんか日付もちゃんとdeserializeされてるじゃないですか!
何やらパッケージ管理下にあるカスタムオブジェクトの日付項目も問題なくJSON.deserializeを使えるようになってましたー。
もちろん、これも動きました。↓
Type objType = Type.forName('List<gii__SalesOrder__c>'); String paramString = '[{"gii__RequiredDate__c":"2011-12-30", "gii__Released__c":true, "Phase__c":"ご来店", "Remarks__c":"ABCDEFGHIJKLMN,4444aaa"}]'; List<gii__SalesOrder__c> testSOs = (List<gii__SalesOrder__c>)JSON.deserialize(paramString, objType); System.debug('** testSOs : ' + testSOs);
↓
14:57:01.629 (11629374000)|USER_DEBUG|[176]|DEBUG|** testSOs : (gii__SalesOrder__c:{gii__RequiredDate__c=2011-12-30 00:00:00, Remarks__c=ABCDEFGHIJKLMN,4444aaa, Phase__c=ご来店, gii__Released__c=true})
とりあえず、思った通りの挙動になったみたいで良かったです。
ではまた次回(※未定)!
Glovia Order Management (on Salesforce) を使ってみようか (9)
久々の更新です。今回はgOMネタで。
Ver5.0 あたり(?)から追加された「買掛請求書」をちょいとイジッてみましょうか。
買掛請求書って?
サプライヤから送付された請求書で、「いついつまでにおいくら万円を支払ってね」といった内容を処理する感じでしょうか。
そんなわけで、gOMでは
購買オーダー発行 → 購買受入
の後にやってくる、という想定で作られています。(そうでないケースにも対応可能ですが、大半はこの流れかと。)
そんなわけで、購買受入後という前提で話を続けます。
買掛請求書の処理
1. 買掛請求書の登録
サプライヤから届いた請求書をgOMに登録します。
2. 購買オーダー受入を検収
買掛請求書を登録した後は、このサプライヤに対する購買受入を消し込みます。この買掛請求書が、何を買ったものに対する請求なのかを紐付ける作業となります。
買掛請求書画面の「購買オーダー受入を検収」ボタンから移動します。
この画面で紐付けしてない購買受入を指定して、買掛請求書と紐付けします。これは完全に手で消し込んでいく作業となります。
もちろん、購買受入は複数紐付けできます。一度保存してから、「購買オーダー受入を検収」ボタンをクリックして、この画面に戻って再度紐付けしていきます。
該当する購買受入を設定すると、「買掛請求書検収」という関連リストにデータが登録されてるのが分かります。
3. 仮受金額の配賦
購買オーダー受入を検収した後の画面です。
ここで
- VAT金額(税額)が計算されている
- 仮受金額(ココではマイナス金額)が発生している
といったあたりがポイントになるかなーと思います。
1. VAT金額(税額)が計算されている について
お気づきの方もいらっしゃると思いますが、gOMでは購買オーダーを発行したときには税額計算していません。購買オーダー画面でも税額に相当する項目はありません。
gOMでは、買掛請求書に対して購買受入を紐付ける際に、税額を計算しているようです。
購買オーダーの税額はサプライヤ側で計算するもの、という前提があって、購買オーダー発行時には税額計算しないようにしているかと思います。また、購買オーダー発行時に税額も計算して発注書を送付する、ということは自社の税ルールをサプライヤ側に押し付けることになるので、それはNGなのかな・・?と。
特に、米国のように地域によって税率が変わるような場合だと、自社とサプライヤで税ルールが異なるケースも多々あるから、税額はサプライヤ側で計算すべし、ということなのでしょうかね。
2. 仮受金額(ココではマイナス金額)が発生している について
gOMで登録されている購買受入を紐付けたときに計算された合計金額(画面上でいう「合計配賦金額」)と、買掛請求書に記載されている金額の差分が仮受金額として残ります。
例えば、値引き調整があったとか消費税の計算ルールに差があって微妙な差額が発生したとか・・でしょうかね。
※この仮受金額を残したままにしておくと、「転記」処理(会計インタフェースへの転記)でエラーとなります。
というわけで、この仮受金額に勘定科目を配賦しましょう。
「買掛請求書勘定科目配賦」にて処理します。
新規買掛請求書勘定科目配賦ボタンから登録画面に移動して、勘定科目/金額を入力して新規登録します。
※予め「勘定科目」マスタを整備しておく必要があります。「総勘定元帳インタフェースメンテナンス」タブよりメンテナンス画面に移動します。
買掛請求書勘定科目配賦を作成すると、仮受金額がゼロ円になっているのが分かります。
これにてサプライヤからの買掛請求書がバッチリ消し込まれた状態となりました!
この状態になってから、最後に「転記」を実行すると、会計インタフェースが作成されます。
※会計インタフェースを作成するには、カスタム設定が事前に必要です。また、会計インタフェースが不要であれば、「転記」を実行する必要はないかと思います。
ちなみに、「転記を取消」をすると、「転記」実行前の状態に戻ります。
会計に関する知識も必要となるので、自分にはなかなか厳しいところがあるのですが、使いこなせるようになると良いですねー。
という感じで「買掛請求書」を使ってみた!というお話でした。
ではっ!