4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Genexus備忘録(実装編)

Last updated at Posted at 2018-11-05

※量が増えてスクロールが面倒になったので記事を分割した。
操作編

文法

なんかパスカルケースっぽい。
VBに近い文法に見える。
Genexus上で書いたコードの実態は、*.cfsファイルに保存されているようだ。

関数一覧?

演算子

残念ながら++とか%はない
!はあるけど別の意味(リテラル)なので注意

&i = 0
&i = &i + 1

// 余りはMod
If Mod(&i, 3) = 0
   ...
EndIf

// ~以外は<>
If &a <> 0
 ...
EndIf

// 比較演算子は==ではなく=
If Not &a = 1
 ...
EndIf

リテラル

!を付けないと、内部的に文字列がため込まれていくらしい...。
再利用か何か狙ってるのだろうか?詳細は不明。

hoge.str = 'hage'
hoge.str = !'page'

If

ElseIfはないらしい

If &a <> 0
 ...
EndIf

Case

Do Case
  Case &a = !'a'
    ...  
  Case &a = !'b'
    ...
  OtherWise
    ...
EndCase

イベント構文

ユーザー定義イベントに数字を併記すると、対応するファンクションキー押下時に処理を割り当てることができる。
ただし、ブラウザ標準の機能が死ぬため注意。F12の開発者ツールとか。

// 起動時
Event Start
EndEvent

// 更新時(ユーザー定義イベント後も動いちゃう)
Event Refresh
EndEvent

// ユーザー定義イベント(F4割り当て)
Event 'sel' 4
EndEvent

機能的なところ

コード埋め込み?

地味に、他言語のコードを直接埋め込めるっぽい。
おそらくは、最初にプロジェクト設定で選択した言語限定だろうけど。

java for (int i = 0; i < 5; i++) {
java ...
java }

シングルクォートで囲っているのは、ユーザー定義イベント。
配置したボタンの名称を変更するには
1:プロパティから「On click Event」で「New」を選ぶ。
2:captionプロパティを編集する。

Enum的なもの

ドメインを使う。
ナレッジベースナビゲータからドメインを開いたら一覧が見れる。
プロパティのEnum Valuesから専用エディタを開ける。

キャスト

変換できないものがあったら0を返すらしい。


val(&str)
str(&num)

SDT

Newしてあげないと、メモリ割り当てされない。
For Eachとかで回してListにpushする時は
ループ毎にNewしないと、参照渡しになる故。

&HOGE_SDT = New()

一度定義したIDを変更する場合は、プロパティ上から編集する。
Structureタブで直接編集すると、元々のIDとは別項目として、新規項目扱いされるらしい。
「Is Collection」にチェックを入れると、リストとして扱ってくれる。

例外

基本は例外という考え方はなく
システムエラー以外は空文字とか0とかにキャストしてくるらしい。

Procedure呼び出し

Callで外から呼び出せる。
パラメータはRules枠で定義できる。

Rulesのパラメータ定義

parm(in: &hoge, out: &hage);

呼び出し方A

hogehogeProc.Call(&hoge, &hage)

呼び出し方B

&hage = hogehogeProc.Udp(&hoge)

最後のout項目限定で、Udp()って呼び出し方すると戻り値として返してくれる。
複数out項目を定義しても、Udp()で返ってくるのは最後の一個だけ。
つまり、他プロシージャの呼び出しの引数に渡せる。

hageProc.Call(hogehogeProc.Udp(&hoge))

プロシージャに複数メソッド定義

Rulesでのパラメタ定義が使えなくなるけど、こんな風に定義できる。

Stub sel(in:&cd, out:&rtn)
  ...
EndStub

Stub del(in:&cd, out:&rtn)
  ...
EndStub

呼び出し側

hoge.sel(&cd, &rtn)
hoge.del(&cd, &rtn)

サブルーチン

privateメソッドを定義。
外部からは呼べない。
戻り値を返せないので、サブルーチン内部ではグローバル変数を書き換える。

Sub 'calc'
  Do 'multiple'
EndSub

セッション

SDTとかのデータの受け渡しはセッションを使える。
先にVariablesタブでWebSessionの変数を定義しとかないと補完が聞かないのでつらい。

// シリアライズ
&webSession.Set('key', &sdts.ToXml())

// デシリアライズ
&sdts.FromXml($webSession.Get('key'))

DB周り

検索条件を絞る

when句を使うと、条件を満たす場合のみ、where句を付与できるようになる。
Likeと検索文字列を'%'と結合させて、前方一致やら部分一致やらを実現できる。

For Each m_shohin Order ms_shohin_cd
    where ms_shohin_cd = &ms_shohin_cd when not &ms_shohin_cd.IsEmpty()
    where ms_shohin_nm like '%' + &ms_shohin_nm + '%' when not &ms_shohin_nm.IsEmpty()
    where ms_shohin_price > &ms_shohin_price when &ms_shohin_price > 0
EndFor

キーさえ一意なら、テーブル名の指定もいらなかったりする。

For Each
  where ms_shohin_cd = &ms_shohin_cd when not &ms_shohin_cd.IsEmpty()
EndFor

外部キーの場合は、逆にテーブル名を指定してあげないと、エラーになる。

// m_shohin_hd, m_shohin_dtlだけを結合したいが、
// テーブル名を省くとms_shohinもくっつけようとしてリレーションNGになる
For Each m_shohin_hd, m_shohin_dtl
  where ms_shohin_cd = &ms_shohin_cd when not &ms_shohin_cd.IsEmpty()
 where m_shohin_hd_del_flg = False
  where m_shohin_dtl_del_flg = False
EndFor

集約はたぶんこう(未検証)

For each
  where ms_shohin_del_flg = False
  &TotalAmt = Sum(ms_shohin_category, ms_shohin_sel_div = !'1')
EndFor

Insert/Update/Delete

// INSERTだけならこれで
New
	ms_shohin_cd = &ms_shohin_cd
	ms_shohin_nm = &ms_shohin_nm
	ms_shohin_price = &ms_shohin_price
Endnew

For Each m_shohin
	where ms_shohin_cd = &ms_shohin_cd
	ms_shohin_nm = &ms_shohin_nm
	ms_shohin_price = &ms_shohin_price
when none
	New
		ms_shohin_cd = &ms_shohin_cd
		ms_shohin_nm = &ms_shohin_nm
		ms_shohin_price = &ms_shohin_price
	Endnew
EndFor

For Each m_shohin
	where ms_shohin_cd = &ms_shohin_cd
	Delete
	&rtn = 1
when none
	&rtn = 2
EndFor

トラブルシューティング

・was wrong...とか言われる
→似たようで互換性がない型が、おそらくAutodefined Variablesで登録されている

・Numeric = Varcharとか言われる
→型が間違っている、Autodefined Variablesのせいなのか、変数定義してないからかは要確認。意図的にやってるならキャストする。

・日付はどうやって初期化するの
→.SetEmpty()を使う

・DBの再編成がこける
→型変更とかのケースでやってしまいがち。DDLはgeneXusが勝手に発行するので、手動でDDLを発行せず、再編成プログラムに任せること。

・実行時にCaused by: com.genexus.GXRuntimeException: org.postgresql.util.PSQLException: ERROR: portal "C_65" does not exist
→整数項目にマイナスつっこもうとしてたり、色々…

・java.lang.reflect.InvocationTargetExceptionが起きる
自分で書いたコードじゃないんだからリフレクションエラー言われてもわけわからねーよぉ!!

ナレッジベースのフォルダ階層の中に出力されたjavaファイル見て、javaベースでロジック追いかけるのが一番早い気がする。
C:\GenKB\JavaModel\web\ws***.java

・portal "C_[0-9]+" does not exist
HTTPステータス 500 - java.lang.reflect.InvocationTargetException

Caused by: com.genexus.GXRuntimeException: org.postgresql.util.PSQLException: ERROR: portal "C_136" does not exist
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2101)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1834)
	at org.postgresql.core.v3.QueryExecutorImpl.fetch(QueryExecutorImpl.java:2036)
	at org.postgresql.jdbc2.AbstractJdbc2ResultSet.next(AbstractJdbc2ResultSet.java:1821)
	at com.genexus.db.driver.GXResultSet.next(Unknown Source)
	at com.genexus.db.ForEachCursor.next(Unknown Source)
	at com.genexus.db.DataStoreProvider.readNext(Unknown Source)

NG

For &Upd_SDT in &Upd_SDTs
	For Each
		where CrtDate = &ServerNow
		OracleAcntgDataKbn = !'9'
		Commit
	EndFor	
EndFor

OK

For &Upd_SDT in &Upd_SDTs
	For Each
		where CrtDate = &ServerNow
		OracleAcntgDataKbn = !'9'
	EndFor
	Commit	
EndFor

For &Upd_SDT in &Upd_SDTs
	For Each
		where CrtDate = &ServerNow
		OracleAcntgDataKbn = !'9'
	EndFor	
EndFor
Commit

ほか

続きは随時追記していく方式で。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?