Code Optimisation

Post on 13-Apr-2017

130 views 0 download

Transcript of Code Optimisation

code optimisationOlivier Deschanels, Senior Consultant

optimise your code, you must

optimise your code, you must

optimise your code, you must

レスポンスの速度を向上させるために

リクエストの効率を良くするために

トラフィック量を減らすために

コードを簡易にするために

保守を楽にするために

将来に備えるために

before coding …

Murphy was an incurable optimist

1

Murphy was an incurable optimist

1

Murphy was an incurable optimist

1

2

Murphy was an incurable optimist

1

2

Murphy was an incurable optimist

1

2

3

Murphy was an incurable optimist

1

2

3

Murphy was an incurable optimist

1

2

3

4

Murphy was an incurable optimist

1

2

3

4

Murphy was an incurable optimist

1

2

3

4

5

Murphy was an incurable optimist

1

2

3

4

5

Murphy was an incurable optimist

C/S isn't just a multiprocess standalone

C/S isn't just a multiprocess standalone

スタンドアロン版でしかコードを検証していなかった …

C/S isn't just a multiprocess standalone

スタンドアロン版でしかコードを検証していなかった …

何が起きているのか理解するためにC/S版でデバッグと検証が必要 …

C/S isn't just a multiprocess standalone

スタンドアロン版でしかコードを検証していなかった …

何が起きているのか理解するためにC/S版でデバッグと検証が必要 …

最初からC/S版で開発していれば時間の節約に

C/S isn't just a multiprocess standalone

wifi makes delays worse

wifi makes delays worse

wifi makes delays worse

wifi makes delays worse

x 1.2

wifi makes delays worse

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

x 7.5

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

x 7.5

Time with 'execute on server' method attribute"サーバー上で実⾏メソッド"属性を有効にした場合

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

÷23

÷6

wifi makes delays worse

0 ms 3,750 ms 7,500 ms 11,250 ms 15,000 ms

÷23

÷6

wifi makes delays worse

know your code activity, you should

know your code activity, you should

know your code activity, you should

1

know your code activity, you should

1

SET DATABASE PARAMETER(Debug log recording;2+4+8+16)

know your code activity, you should

1

2

know your code activity, you should

1

2

3

know your code activity, you should

1

2

3

SET DATABASE PARAMETER(Debug log recording;0)

know your code activity, you should

1

2

3

4 logs

know your code activity, you should

1

2

3

4 logs

5 4DDebugLog_1.txt

know your code activity, you should

1

2

3

4 logs

5 4DDebugLog_1.txt

know your code activity, you should

1

2

3

4 logs

5 4DDebugLog_1.txt

too much info; select you must

too much info; select you must

1

too much info; select you must

1

2

too much info; select you must

1

2

too much info; select you must

1

2

3

too much info; select you must

1

2

3

too much info; select you must

1

2

3

4

too much info; select you must

SET DATABASE PARAMETER(Log command list;"277") SET DATABASE PARAMETER(Debug log recording;2+4+8+16)

1

2

3

4

too much info; select you must

SET DATABASE PARAMETER(Log command list;"277") SET DATABASE PARAMETER(Debug log recording;2+4+8+16)SET DATABASE PARAMETER(Log command list;"277;341") SET DATABASE PARAMETER(Debug log recording;2+4+8+16)

1

2

3

4

too much info; select you must

SET DATABASE PARAMETER(Log command list;"277") SET DATABASE PARAMETER(Debug log recording;2+4+8+16)SET DATABASE PARAMETER(Log command list;"277;341") SET DATABASE PARAMETER(Debug log recording;2+4+8+16)

QUERY (277) および QUERY SELECTION (341)

コマンドを監視

1

2

3

4

set the flags

SET DATABASE PARAMETER(Debug log recording; 2 + 4 + 8 + 16)

set the flags

SET DATABASE PARAMETER(Debug log recording; 2 + 4 + 8 + 16)

2 : 引数も記録(メソッドおよびコマンド)

4 : タブ区切りフォーマット

8 : 遅延書き込みモード

16 : プラグインも対象

set the flags

know your code activity, you should

know your code activity, you should

1

know your code activity, you should

1

SET DATABASE PARAMETER(Log command list;"") SET DATABASE PARAMETER(Debug log recording;4+8+16)

know your code activity, you should

1

2

know your code activity, you should

1

2

3

know your code activity, you should

1

2

3

know your code activity, you should

1

2

3

4

know your code activity, you should

1

2

3

4

5

know your code activity, you should

1

2

3

4

5

6

1

1

2

1

2

3

1

2

3

4

1

2

3

4

5

1

2

3

4

5

SET DATABASE PARAMETER(Circular log limitation;10)

1

2

3

4

5

SET DATABASE PARAMETER(Circular log limitation;10)

10 x 10MB = 最⼤100MB

reduce the use of variables, you must

variable and variables table

1

variable and variables table

1

2

variable and variables table

1

2

3

variable and variables table

1

2

3

4

variable and variables table

1

2

3

4

5

variable and variables table

1

2

3

4

5

6

variable and variables table

サーバー

クライアント#1

クライアント#2

P1PR1

グローバルプロセス裏⽅のツインプロセス

ネットワーク接続

このプロセスが実⾏ : - トリガ - "サーバー上で実⾏"

P1

P2

PR1

PR2

P1

P2

$P3

PR1

PR2

$ローカルプロセス

P1

P2

$P3

PR1

PR2

P1'

$P2'

PR1'

P1

P2

$P3

PR1

PR2

P1'

$P2'

PR1'

SP2

SP1

ストアドプロシージャー

P1

P2

$P3

PR1

PR2

P1'

$P2'

PR1'

SP2

SP1

WP2

WP3

WP1

Webプロセス

P1

P2

$P3

PR1

PR2

P1'

$P2'

PR1'

SP2

SP1

WP2

WP3

WP1

コンパイル

モード

P1

P2

$P3

PR1

PR2

<>

P1'

$P2'

PR1'

SP2

SP1

WP2

WP3

WP1

インタープロセス変数テーブル

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

SP2

SP1

WP2

WP3

WP1

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

SP2

SP1

WP2

WP3

WP1

プロセス変数テーブル

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2

SP1

WP2

WP3

WP1

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

V

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

V

V

V

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

V

V

V

<>CV

<>CV

コンポーネント#1の インタープロセス変数テーブル

コンポーネント#2の インタープロセス変数テーブル

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

V

V

V

<>CV

<>CV

<>CV

<>CV

<>CV

<>CV

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

V

V

V

CVCV

<>CV

<>CV

<>CV

<>CV

<>CV

<>CV

コンポーネント#1の プロセス変数テーブル

コンポーネント#2の プロセス変数テーブル

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

V

V

V

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CV CV

CV CV

CV CV

<>CV

<>CV

<>CV

<>CV

<>CV

<>CV

コンパイル

モード

P1

P2

$P3

PR1

PR2

<> <>

P1'

$P2'

<>PR1'

V

V

V

V

V

SP2 V

SP1 V

WP2 V

WP3 V

WP1 V

V

V

V

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CVCV

CV CV

CV CV

CV CV

<>CV

<>CV

<>CV

<>CV

<>CV

<>CV

コンパイル

モード

プロセス変数テーブルのサイズに無頓着であってはいけない

control the size of process variables table

1

control the size of process variables table

1

control the size of process variables table

1

2

control the size of process variables table

1

2

control the size of process variables table

1

2

3

control the size of process variables table

1

2

3

control the size of process variables table

1

2

3

4

control the size of process variables table

1

2

3

4

control the size of process variables table

1

2

3

4

5

control the size of process variables table

decrease the size of process variables table

decrease the size of process variables table

1

decrease the size of process variables table

1

decrease the size of process variables table

1

decrease the size of process variables table

1

decrease the size of process variables table

1

2

bOk bValid

bValidate b_Ok

buttonOK

decrease the size of process variables table

1

2

decrease the size of process variables table

1

2

decrease the size of process variables table

1

2

3

decrease the size of process variables table

1

2

3

decrease the size of process variables table

1

2

3

decrease the size of process variables table

1

2

3

decrease the size of process variables table

1

2

3

decrease the size of process variables table

1

2

3

4

decrease the size of process variables table

1

2

3

4

decrease the size of process variables table

1

2

3

4

decrease the size of process variables table

1

2

3

4

use dynamic variables

1

use dynamic variables

1

2

use dynamic variables

1

2

3

use dynamic variables

1

2

3

use dynamic variables

1

2

3

use dynamic variables

1

2

3

use dynamic variables

1

2

3

use dynamic variables

don't push your luck

don't push your luck

don't push your luck

don't push your luck

プロセス変数を使っても⼤丈夫です!

don't push your luck

プロセス変数を使っても⼤丈夫です!

ほんとう? それを聴いて安⼼した

don't push your luck

プロセス変数を使っても⼤丈夫です!"最先端"であるためにコードを複雑にする必要はありません変数のサイズに気を配るのは⼤事ですが,極端に⾛らないで

don't push your luck

プロセス変数を使っても⼤丈夫です!"最先端"であるためにコードを複雑にする必要はありません変数のサイズに気を配るのは⼤事ですが,極端に⾛らないで

それに今ならオブジェクト変数が…

don't push your luck

group the variables in an object, you can

無数のフォームローカル変数を オブジェクト型のプロセス変数に置換:

group the variables in an object, you can

無数のフォームローカル変数を オブジェクト型のプロセス変数に置換:

{"onTimerMessage":"refresh", "PreviousFormEvent":27, "LastKeystroke":"C", "OnErrorMethodToRestore":"General_Error_Call", "OnEventMethodToRestore":"", "CountryCustomer":"FR", "CurrentQuoteUUID":"EF455411221114778AB3ED45DD", "ListOfCountryInWishList":["US","FR","UK","SA","AU"] }

group the variables in an object, you can

無数のフォームローカル変数を オブジェクト型のプロセス変数に置換:

{"onTimerMessage":"refresh", "PreviousFormEvent":27, "LastKeystroke":"C", "OnErrorMethodToRestore":"General_Error_Call", "OnEventMethodToRestore":"", "CountryCustomer":"FR", "CurrentQuoteUUID":"EF455411221114778AB3ED45DD", "ListOfCountryInWishList":["US","FR","UK","SA","AU"] }

1個のプロセス変数に保存: form_context

group the variables in an object, you can

無数のフォームローカル変数を オブジェクト型のプロセス変数に置換:

{"onTimerMessage":"refresh", "PreviousFormEvent":27, "LastKeystroke":"C", "OnErrorMethodToRestore":"General_Error_Call", "OnEventMethodToRestore":"", "CountryCustomer":"FR", "CurrentQuoteUUID":"EF455411221114778AB3ED45DD", "ListOfCountryInWishList":["US","FR","UK","SA","AU"] }

1個のプロセス変数に保存: form_context

プロセス変数テーブルに 16バイト追加することに

group the variables in an object, you can

無数のフォームローカル変数を オブジェクト型のプロセス変数に置換:

{"onTimerMessage":"refresh", "PreviousFormEvent":27, "LastKeystroke":"C", "OnErrorMethodToRestore":"General_Error_Call", "OnEventMethodToRestore":"", "CountryCustomer":"FR", "CurrentQuoteUUID":"EF455411221114778AB3ED45DD", "ListOfCountryInWishList":["US","FR","UK","SA","AU"] }

1個のプロセス変数に保存: form_context

プロセス変数テーブルに 16バイト追加することに

わずか16バイトで整理できて⼤変お買い得!

group the variables in an object, you can

無数のフォームローカル変数を オブジェクト型のプロセス変数に置換:

{"onTimerMessage":"refresh", "PreviousFormEvent":27, "LastKeystroke":"C", "OnErrorMethodToRestore":"General_Error_Call", "OnEventMethodToRestore":"", "CountryCustomer":"FR", "CurrentQuoteUUID":"EF455411221114778AB3ED45DD", "ListOfCountryInWishList":["US","FR","UK","SA","AU"] }

1個のプロセス変数に保存: form_context

プロセス変数テーブルに 16バイト追加することに

わずか16バイトで整理できて⼤変お買い得!

属性を追加するだけ拡張: フォームに オブジェクトを追加する必要なし

group the variables in an object, you can

example with a form_context

OB SET(form_context;"currentCountry";"France")

$ref:=Open form window("country_selector") DIALOG("country_selector") CLOSE WINDOW($ref )

$return_country:=OB Get(form_context;"currentCountry")

example with a form_context

OB SET(form_context;"currentCountry";"France")

$ref:=Open form window("country_selector") DIALOG("country_selector") CLOSE WINDOW($ref )

$return_country:=OB Get(form_context;"currentCountry")

example with a form_context

OB SET(form_context;"currentCountry";"France")

$ref:=Open form window("country_selector") DIALOG("country_selector") CLOSE WINDOW($ref )

$return_country:=OB Get(form_context;"currentCountry")

$evt:=Form event Case of : ($evt=On Load) $currentCountry:=OB Get(form_context;"currentCountry") ALL RECORDS([Country]) DISTINCT VALUES([Country]Continent;_continent) If ($currentCountry="") _continent:=1 OB SET(form_context;"onTimerMessage";"changeContinent") SET TIMER(-1) Else QUERY([Country];[Country]Name=$currentCountry) _continent:=Find in array(_continent;[Country]Continent) QUERY([Country];[Country]Continent=_continent{_continent}) DISTINCT VALUES([Country]Name;_country) _country:=Find in array(_country;$currentCountry) End if

: ($evt=On Timer) SET TIMER(0) $onTimerMessage:=OB Get(form_context;"onTimerMessage";Is text) OB REMOVE(form_context;"onTimerMessage") Case of : ($onTimerMessage="changeContinent") QUERY([Country];[Country]Continent=_continent{_continent}) DISTINCT VALUES([Country]Name;_country) _country:=1 End case End case

example with a form_context

OB SET(form_context;"currentCountry";"France")

$ref:=Open form window("country_selector") DIALOG("country_selector") CLOSE WINDOW($ref )

$return_country:=OB Get(form_context;"currentCountry")

$evt:=Form event Case of : ($evt=On Load) $currentCountry:=OB Get(form_context;"currentCountry") ALL RECORDS([Country]) DISTINCT VALUES([Country]Continent;_continent) If ($currentCountry="") _continent:=1 OB SET(form_context;"onTimerMessage";"changeContinent") SET TIMER(-1) Else QUERY([Country];[Country]Name=$currentCountry) _continent:=Find in array(_continent;[Country]Continent) QUERY([Country];[Country]Continent=_continent{_continent}) DISTINCT VALUES([Country]Name;_country) _country:=Find in array(_country;$currentCountry) End if

: ($evt=On Timer) SET TIMER(0) $onTimerMessage:=OB Get(form_context;"onTimerMessage";Is text) OB REMOVE(form_context;"onTimerMessage") Case of : ($onTimerMessage="changeContinent") QUERY([Country];[Country]Continent=_continent{_continent}) DISTINCT VALUES([Country]Name;_country) _country:=1 End case End case

OB SET(form_context;"onTimerMessage";"changeContinent") SET TIMER(-1)

example with a form_context

OB SET(form_context;"currentCountry";"France")

$ref:=Open form window("country_selector") DIALOG("country_selector") CLOSE WINDOW($ref )

$return_country:=OB Get(form_context;"currentCountry")

$evt:=Form event Case of : ($evt=On Load) $currentCountry:=OB Get(form_context;"currentCountry") ALL RECORDS([Country]) DISTINCT VALUES([Country]Continent;_continent) If ($currentCountry="") _continent:=1 OB SET(form_context;"onTimerMessage";"changeContinent") SET TIMER(-1) Else QUERY([Country];[Country]Name=$currentCountry) _continent:=Find in array(_continent;[Country]Continent) QUERY([Country];[Country]Continent=_continent{_continent}) DISTINCT VALUES([Country]Name;_country) _country:=Find in array(_country;$currentCountry) End if

: ($evt=On Timer) SET TIMER(0) $onTimerMessage:=OB Get(form_context;"onTimerMessage";Is text) OB REMOVE(form_context;"onTimerMessage") Case of : ($onTimerMessage="changeContinent") QUERY([Country];[Country]Continent=_continent{_continent}) DISTINCT VALUES([Country]Name;_country) _country:=1 End case End case

OB SET(form_context;"onTimerMessage";"changeContinent") SET TIMER(-1)

OB SET(form_context;"currentCountry";_country{_country}) ACCEPT

example with a form_context

lighter is faster!

don't use every possible fields

don't use every possible fields

こんにちは。150フィールドの者です。

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから でも,⼤概は普通のケースですよね?

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから でも,⼤概は普通のケースですよね?

備えあれば憂いなし,ってね!

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから でも,⼤概は普通のケースですよね?

備えあれば憂いなし,ってね!

コスト的にはどうなの?

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから でも,⼤概は普通のケースですよね?

備えあれば憂いなし,ってね!

コスト的にはどうなの?

未使⽤フィールドは空だからタダですよ

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから でも,⼤概は普通のケースですよね?

備えあれば憂いなし,ってね!

コスト的にはどうなの?

未使⽤フィールドは空だからタダですよ

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから でも,⼤概は普通のケースですよね?

備えあれば憂いなし,ってね!

コスト的にはどうなの?

未使⽤フィールドは空だからタダですよ

don't use every possible fields

こんにちは。150フィールドの者です。はじめまして!

いろんなケースに対応できるんですよ

ほんとうに?

もちろん! 想定シナリオを100%網羅していますから でも,⼤概は普通のケースですよね?

備えあれば憂いなし,ってね!

コスト的にはどうなの?

未使⽤フィールドは空だからタダですよ

don't use every possible fields

empty isn't free

150フィールドのテーブルempty isn't free

レコードのサイズ 150フィールドのテーブル

ヘッダー 32 バイト 32 バイト

データ 実際のサイズ 実際のサイズ

µストラクチャ 8 バイト×フィールド数 1,200 バイト

合計 最低 1.2 Kb レコード毎

150フィールドのテーブルempty isn't free

レコードのサイズ 150フィールドのテーブル

ヘッダー 32 バイト 32 バイト

データ 実際のサイズ 実際のサイズ

µストラクチャ 8 バイト×フィールド数 1,200 バイト

合計 最低 1.2 Kb レコード毎

150フィールドのテーブルempty isn't free

try to keep stable field sizes

try to keep stable field sizes

try to keep stable field sizes

a

try to keep stable field sizes

a

b

try to keep stable field sizes

a

b

c

try to keep stable field sizes

a

b

c

d

try to keep stable field sizes

a

b

c

d

e

try to keep stable field sizes

a

b

c

d

e

f

try to keep stable field sizes

a

a

b

a

b

c

a

b

c

d

a

b

c

d

e

a

b

c

d

e

f

a

b

c

d

e

f

g

a

b

c

d

e

f

g

h

"all you can store" syndrome

"all you can store" syndrome

"all you can store" syndrome

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

"all you can store" syndrome

# フィールド

9 Phone1

10 Phone2

11 Fax

35 Phone3

90 Portable

105 email

120 email2

you must unlearn what you have learned

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

カレントプロセス内で有効

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

カレントプロセス内で有効

すべてのリレーションを変更する 1個のリレーションだけを変更する

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

カレントプロセス内で有効

すべてのリレーションを変更する 1個のリレーションだけを変更する

True, False Do not modify, Structure config., Manual, Automatic

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

カレントプロセス内で有効

すべてのリレーションを変更する 1個のリレーションだけを変更する

True, False Do not modify, Structure config., Manual, Automatic

ストラクチャー定義の⾃動リレーションは変更できない ストラクチャー定義の⾃動リレーションも変更できる

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

カレントプロセス内で有効

すべてのリレーションを変更する 1個のリレーションだけを変更する

True, False Do not modify, Structure config., Manual, Automatic

ストラクチャー定義の⾃動リレーションは変更できない ストラクチャー定義の⾃動リレーションも変更できる

"True" はリレーションをロックする;その場合 SET FIELD RELATION

は無視されてしまう副作⽤なし

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

カレントプロセス内で有効

すべてのリレーションを変更する 1個のリレーションだけを変更する

True, False Do not modify, Structure config., Manual, Automatic

ストラクチャー定義の⾃動リレーションは変更できない ストラクチャー定義の⾃動リレーションも変更できる

"True" はリレーションをロックする;その場合 SET FIELD RELATION

は無視されてしまう副作⽤なし

!

you must unlearn what you have learned

SET AUTOMATIC RELATIONS SET FIELD RELATION

カレントプロセス内で有効

すべてのリレーションを変更する 1個のリレーションだけを変更する

True, False Do not modify, Structure config., Manual, Automatic

ストラクチャー定義の⾃動リレーションは変更できない ストラクチャー定義の⾃動リレーションも変更できる

"True" はリレーションをロックする;その場合 SET FIELD RELATION

は無視されてしまう副作⽤なし

!

互換性のために残されている 効率⾯で優れている

you must unlearn what you have learned

you must unlearn what you have learned

QUERY BY FORMULA QUERY BY FORMULAQUERY SELECTION BY FORMULA

you must unlearn what you have learned

QUERY BY FORMULA QUERY BY FORMULA

インデックスを使⽤しないシーケンシャル検索 インデックス検索

QUERY SELECTION BY FORMULA

you must unlearn what you have learned

QUERY BY FORMULA QUERY BY FORMULA

インデックスを使⽤しないシーケンシャル検索 インデックス検索

サーバー側でフォーミュラを評価クライアント側でフォーミュラ式を評価

QUERY SELECTION BY FORMULA

you must unlearn what you have learned

QUERY BY FORMULA QUERY BY FORMULA

インデックスを使⽤しないシーケンシャル検索 インデックス検索

サーバー側でフォーミュラを評価

⾃動的にJOINを実⾏

クライアント側でフォーミュラ式を評価

レコード1件ずつクライアントに転送

JOINを定義して使⽤

QUERY SELECTION BY FORMULA

you must unlearn what you have learned

QUERY BY FORMULA QUERY BY FORMULA

インデックスを使⽤しないシーケンシャル検索 インデックス検索

サーバー側でフォーミュラを評価

⾃動的にJOINを実⾏

クライアント側でフォーミュラ式を評価

レコード1件ずつクライアントに転送

JOINを定義して使⽤

以前のアドバイス : 利⽤は慎重に,できる限りQUERY

SELECTIONで対応

現在のアドバイス : v11の主要強化ポイントのひとつ

積極的に使⽤するべき!

QUERY SELECTION BY FORMULA

you must unlearn what you have learned

you must unlearn what you have learned

EXECUTE ON CLIENT EXECUTE ON CLIENTREGISTER CLIENT(name;period) REGISTER CLIENT(name)

you must unlearn what you have learned

EXECUTE ON CLIENT EXECUTE ON CLIENTREGISTER CLIENT(name;period) REGISTER CLIENT(name)

登録後,クライアントは定期的に,デフォルトでは2秒毎に,サーバー あるいは別のクライアントから

呼び出されているか問い合わせる

サーバーは必要なときに実⾏リクエストを直接クライアントに送信する

you must unlearn what you have learned

EXECUTE ON CLIENT EXECUTE ON CLIENTREGISTER CLIENT(name;period) REGISTER CLIENT(name)

登録後,クライアントは定期的に,デフォルトでは2秒毎に,サーバー あるいは別のクライアントから

呼び出されているか問い合わせる

サーバーは必要なときに実⾏リクエストを直接クライアントに送信する

PULLモード PUSHモード

you must unlearn what you have learned

EXECUTE ON CLIENT EXECUTE ON CLIENTREGISTER CLIENT(name;period) REGISTER CLIENT(name)

登録後,クライアントは定期的に,デフォルトでは2秒毎に,サーバー あるいは別のクライアントから

呼び出されているか問い合わせる

サーバーは必要なときに実⾏リクエストを直接クライアントに送信する

PULLモード PUSHモード

⼤量リクエストの可能性 必要最低限のリクエスト数

you must unlearn what you have learned

you must unlearn what you have learned

TRIGGER TRIGGER

you must unlearn what you have learned

TRIGGER TRIGGER

トリガはアトミックな操作: トリガが実⾏されている間,

サーバー側のコードがすべて待機トリガは実⾏中のコードを停⽌しない

you must unlearn what you have learned

TRIGGER TRIGGER

トリガはアトミックな操作: トリガが実⾏されている間,

サーバー側のコードがすべて待機トリガは実⾏中のコードを停⽌しない

コマンドではなく関数

you must unlearn what you have learned

TRIGGER TRIGGER

トリガはアトミックな操作: トリガが実⾏されている間,

サーバー側のコードがすべて待機トリガは実⾏中のコードを停⽌しない

コマンドではなく関数 C_LONGINT($0) $0:=0

you must unlearn what you have learned

TRIGGER TRIGGER

トリガはアトミックな操作: トリガが実⾏されている間,

サーバー側のコードがすべて待機トリガは実⾏中のコードを停⽌しない

コマンドではなく関数 C_LONGINT($0) $0:=0

トリガコードでトランザクションを使⽤しない! エラーコード($0) を活⽤する

you must unlearn what you have learned

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

end if

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

end if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

end if

$reference:=[Customer]Reference

$recNum:=Find in field([Customer]Reference;$reference)

If ($recNum>=0)//do something

End if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

end if

$reference:=[Customer]Reference

$recNum:=Find in field([Customer]Reference;$reference)

If ($recNum>=0)//do something

End if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

Find in field でバッチリ解決!

at the end, house of cards falls

at the end, house of cards falls

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdayPUSH RECORD([Customer])

QUERY([Customer];[Customer]firstName=$firstName;*)QUERY([Customer];[Customer]lastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

End if

at the end, house of cards falls

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdayPUSH RECORD([Customer])

QUERY([Customer];[Customer]firstName=$firstName;*)QUERY([Customer];[Customer]lastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

End if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

at the end, house of cards falls

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdayPUSH RECORD([Customer])

QUERY([Customer];[Customer]firstName=$firstName;*)QUERY([Customer];[Customer]lastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

End if

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]Birthday

SET QUERY DESTINATION(Into variable;$nb)QUERY([Customer];[Customer]FirstName=$firstName;*)QUERY([Customer];[Customer]LastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)SET QUERY DESTINATION(Into current selection)

If ($nb=0)//do something

End if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

at the end, house of cards falls

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdayPUSH RECORD([Customer])

QUERY([Customer];[Customer]firstName=$firstName;*)QUERY([Customer];[Customer]lastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

End if

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]Birthday

SET QUERY DESTINATION(Into variable;$nb)QUERY([Customer];[Customer]FirstName=$firstName;*)QUERY([Customer];[Customer]LastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)SET QUERY DESTINATION(Into current selection)

If ($nb=0)//do something

End if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

SET QUERY DESTINATION カレントセレクション・レコードを変更せずにクエリを実⾏

at the end, house of cards falls

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdayPUSH RECORD([Customer])

QUERY([Customer];[Customer]firstName=$firstName;*)QUERY([Customer];[Customer]lastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

End if

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]Birthday

SET QUERY DESTINATION(Into variable;$nb)QUERY([Customer];[Customer]FirstName=$firstName;*)QUERY([Customer];[Customer]LastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)SET QUERY DESTINATION(Into current selection)

If ($nb=0)//do something

End if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdaySET QUERY LIMIT(1)SET QUERY DESTINATION(Into variable;$nb)QUERY([Customer];[Customer]FirstName=$firstName;*)QUERY([Customer];[Customer]LastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)SET QUERY DESTINATION(Into current selection)SET QUERY LIMIT(0)If ($nb=0)

//do somethingEnd if

SET QUERY DESTINATION カレントセレクション・レコードを変更せずにクエリを実⾏

at the end, house of cards falls

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdayPUSH RECORD([Customer])

QUERY([Customer];[Customer]firstName=$firstName;*)QUERY([Customer];[Customer]lastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)$nb:=Records in selection([Customer])

POP RECORD([Customer])

If ($nb=0)//do something

End if

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]Birthday

SET QUERY DESTINATION(Into variable;$nb)QUERY([Customer];[Customer]FirstName=$firstName;*)QUERY([Customer];[Customer]LastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)SET QUERY DESTINATION(Into current selection)

If ($nb=0)//do something

End if

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

$firstName:=[Customer]FirstName$lastName:=[Customer]LastName$birthday:=[Customer]BirthdaySET QUERY LIMIT(1)SET QUERY DESTINATION(Into variable;$nb)QUERY([Customer];[Customer]FirstName=$firstName;*)QUERY([Customer];[Customer]LastName=$lastName;*)QUERY([Customer];[Customer]Birthday=$birthday)SET QUERY DESTINATION(Into current selection)SET QUERY LIMIT(0)If ($nb=0)

//do somethingEnd if

SET QUERY LIMIT 0 でリミットを解除

SET QUERY DESTINATION カレントセレクション・レコードを変更せずにクエリを実⾏

at the end, house of cards falls

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$firstName:=[Customer]FirstName$lastName:=[Customer]LastName

POP RECORD([Customer])

//do something with $firstName, $lastName ...

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$firstName:=[Customer]FirstName$lastName:=[Customer]LastName

POP RECORD([Customer])

//do something with $firstName, $lastName ...

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$firstName:=[Customer]FirstName$lastName:=[Customer]LastName

POP RECORD([Customer])

//do something with $firstName, $lastName ...

$reference:=[Customer]Reference$firstName:=""$lastName:=""

Begin SQLselect FirstName, LastName from Customerwhere Reference=:$referenceinto :$firstName, :$lastName

End SQL

//do something with $firstName, $lastName ...

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$firstName:=[Customer]FirstName$lastName:=[Customer]LastName

POP RECORD([Customer])

//do something with $firstName, $lastName ...

$reference:=[Customer]Reference$firstName:=""$lastName:=""

Begin SQLselect FirstName, LastName from Customerwhere Reference=:$referenceinto :$firstName, :$lastName

End SQL

//do something with $firstName, $lastName ...

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

SQL カレントセレクション・レコードを 変更せずにレコードの値を取り出すことができる

at the end, house of cards falls

$reference:=[Customer]ReferencePUSH RECORD([Customer])

QUERY([Customer];[Customer]Reference=$reference)$firstName:=[Customer]FirstName$lastName:=[Customer]LastName

POP RECORD([Customer])

//do something with $firstName, $lastName ...

$reference:=[Customer]Reference$firstName:=""$lastName:=""

Begin SQLselect FirstName, LastName from Customerwhere Reference=:$referenceinto :$firstName, :$lastName

End SQL

//do something with $firstName, $lastName ...

PUSH / POP ロジックはとても⾼価な処理 セレクション変更・クエリ・メモリの読み書き…

SQL カレントセレクション・レコードを 変更せずにレコードの値を取り出すことができる

別⾔語の使⽤は⾃由!

at the end, house of cards falls

a little more knowledge lights our way

QUERY([Customer];[Customer]LastName="Skywalker")CREATE SET([Customer];"SkywalkerFamilly")

a little more knowledge lights our way

QUERY([Customer];[Customer]LastName="Skywalker")CREATE SET([Customer];"SkywalkerFamilly")

QUERY+CREATE SET: 2度のネットワーク通信・カレントセレクションの変更・カレントレコードの

変更・カレントレコードのロック

a little more knowledge lights our way

QUERY([Customer];[Customer]LastName="Skywalker")CREATE SET([Customer];"SkywalkerFamilly")

SET QUERY DESTINATION(Into set;"SkywalkerFamilly")QUERY([Customer];[Customer]LastName="Skywalker")SET QUERY DESTINATION(Into current selection)

QUERY+CREATE SET: 2度のネットワーク通信・カレントセレクションの変更・カレントレコードの

変更・カレントレコードのロック

a little more knowledge lights our way

QUERY([Customer];[Customer]LastName="Skywalker")CREATE SET([Customer];"SkywalkerFamilly")

SET QUERY DESTINATION(Into set;"SkywalkerFamilly")QUERY([Customer];[Customer]LastName="Skywalker")SET QUERY DESTINATION(Into current selection)

QUERY+CREATE SET: 2度のネットワーク通信・カレントセレクションの変更・カレントレコードの

変更・カレントレコードのロック

SET QUERY DESTINATION+QUERY: 1度のネットワーク通信・セットを作成するだけ

a little more knowledge lights our way

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("parameters"))IDLE

End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("parameters"))IDLE

End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

"parameters" はグローバルセマフォ

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("parameters"))IDLE

End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

"parameters" はグローバルセマフォ

"<>arrayParameters" は インタープロセス変数

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("parameters"))IDLE

End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

"parameters" はグローバルセマフォ

"<>arrayParameters" は インタープロセス変数

サーバー側で管理

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("parameters"))IDLE

End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

"parameters" はグローバルセマフォ

"<>arrayParameters" は インタープロセス変数

サーバー側で管理

クライアント側で管理

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("parameters"))IDLE

End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

"parameters" はグローバルセマフォ

"<>arrayParameters" は インタープロセス変数

サーバー側で管理

クライアント側で管理

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("parameters"))IDLE

End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

貴様はテロリストか!

"parameters" はグローバルセマフォ

"<>arrayParameters" は インタープロセス変数

サーバー側で管理

クライアント側で管理

the sounds of silence, respect you must

While (Semaphore("parameters")) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

ARRAY TEXT(<>arrayParameter;0)

the sounds of silence, respect you must

While (Semaphore("parameters")) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("$parameters";500)) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("$parameters")

the sounds of silence, respect you must

While (Semaphore("parameters")) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("$parameters";500)) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("$parameters")

"$parameters" はローカルセマフォ

the sounds of silence, respect you must

While (Semaphore("parameters")) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("$parameters";500)) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("$parameters")

"$parameters" はローカルセマフォクライアント側で管理

the sounds of silence, respect you must

While (Semaphore("parameters")) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("parameters")

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("$parameters";500)) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("$parameters")

"$parameters" はローカルセマフォクライアント側で管理

セマフォがセットされるまで500tick待機する

the sounds of silence, respect you must

ARRAY TEXT(<>arrayParameter;0)

While (Semaphore("$parameters";500)) IDLE End while

APPEND TO ARRAY(<>arrayParameter;$newValue)

CLEAR SEMAPHORE("$parameters")

"$parameters" はローカルセマフォクライアント側で管理

セマフォがセットされるまで500tick待機する

型をしっかり憶えましょう🙂

the sounds of silence, respect you must

still remains within the sound of silence

still remains within the sound of silence

リストボックス#1 セレクション, 特殊型

リストボックス#2 セレクション, 汎⽤型

still remains within the sound of silence

リストボックス#1 セレクション, 特殊型

リストボックス#2 セレクション, 汎⽤型

still remains within the sound of silence

リストボックス#1 セレクション, 特殊型

リストボックス#2 セレクション, 汎⽤型

still remains within the sound of silence

リストボックス#1 セレクション, 特殊型

リストボックス#2 セレクション, 汎⽤型

still remains within the sound of silence

リストボックス#1 セレクション, 特殊型

リストボックス#2 セレクション, 汎⽤型

still remains within the sound of silence

リストボックス#1 セレクション, 特殊型

リストボックス#2 セレクション, 汎⽤型

ハイライトセットは必要がある場合にだけ設定 セットの名前に注意を払うこと

still remains within the sound of silence

kill good old generic

//$sum:=Array_Sum(->myArray) C_POINTER($1;$array) C_REAL($0)

$array:=$1

ASSERT(\ (Type($array->)=Real array)\ | (Type($array->)=LongInt array)\ | (Type($array->)=Integer array)\ ;"Array must be a numeric")

$sum:=0 For ($i;1;Size of array($array->)) $sum:=$sum+$array->{$i} End for

$0:=$sum

kill good old generic

//$sum:=Array_Sum(->myArray) C_POINTER($1;$array) C_REAL($0)

$array:=$1

ASSERT(\ (Type($array->)=Real array)\ | (Type($array->)=LongInt array)\ | (Type($array->)=Integer array)\ ;"Array must be a numeric")

$sum:=0 For ($i;1;Size of array($array->)) $sum:=$sum+$array->{$i} End for

$0:=$sum

$sum:=Sum(myArray)

kill good old generic

//$sum:=Array_Sum(->myArray) C_POINTER($1;$array) C_REAL($0)

$array:=$1

ASSERT(\ (Type($array->)=Real array)\ | (Type($array->)=LongInt array)\ | (Type($array->)=Integer array)\ ;"Array must be a numeric")

$sum:=0 For ($i;1;Size of array($array->)) $sum:=$sum+$array->{$i} End for

$0:=$sum

$sum:=Sum(myArray)

v13以降,"Sum" "Min" "Max" などの統計関数は配列に対応

kill good old generic

kill good old generic, you can

ReadWrite(->[Contact])

kill good old generic, you can

//ReadWrite(->table) C_POINTER($1;$table)

$table:=$1

If (Read only state($table->)) READ WRITE($table->) End if

ReadWrite(->[Contact])

kill good old generic, you can

//ReadWrite(->table) C_POINTER($1;$table)

$table:=$1

If (Read only state($table->)) READ WRITE($table->) End if

ReadWrite(->[Contact])

v2004では,サーバーをコールしたので,READ WRITEを実⾏する前に 状態を調べることは有⽤だった

kill good old generic, you can

//ReadWrite(->table) C_POINTER($1;$table)

$table:=$1

If (Read only state($table->)) READ WRITE($table->) End if

ReadWrite(->[Contact])

READ WRITE([Contact])

v2004では,サーバーをコールしたので,READ WRITEを実⾏する前に 状態を調べることは有⽤だった

kill good old generic, you can

//ReadWrite(->table) C_POINTER($1;$table)

$table:=$1

If (Read only state($table->)) READ WRITE($table->) End if

ReadWrite(->[Contact])

READ WRITE([Contact])

v2004では,サーバーをコールしたので,READ WRITEを実⾏する前に 状態を調べることは有⽤だった

v11以降,リクエストがサーバーに 送信されるまでREAD WRITEは

保留されるようになったのでこれで良い

kill good old generic, you can

//ReadWrite(->table) C_POINTER($1;$table)

$table:=$1

If (Read only state($table->)) READ WRITE($table->) End if

ReadWrite(->[Contact])

READ WRITE([Contact])

v2004では,サーバーをコールしたので,READ WRITEを実⾏する前に 状態を調べることは有⽤だった

v11以降,リクエストがサーバーに 送信されるまでREAD WRITEは

保留されるようになったのでこれで良い

毎回のアップグレード後に必ずチェックするべき項⽬のひとつ

kill good old generic, you can

//ReadWrite(->table) C_POINTER($1;$table)

$table:=$1

If (Read only state($table->)) READ WRITE($table->) End if

ReadWrite(->[Contact])

READ WRITE([Contact])

v2004では,サーバーをコールしたので,READ WRITEを実⾏する前に 状態を調べることは有⽤だった

v11以降,リクエストがサーバーに 送信されるまでREAD WRITEは

保留されるようになったのでこれで良い

毎回のアップグレード後に必ずチェックするべき項⽬のひとつ

何年も開いていない汎⽤コードは腐った⾷品と同じ: 捨てるか運を天に任せるか

kill good old generic, you can

//ReadWrite(->table) C_POINTER($1;$table)

$table:=$1

If (Read only state($table->)) READ WRITE($table->) End if

ReadWrite(->[Contact])

READ WRITE([Contact])

v2004では,サーバーをコールしたので,READ WRITEを実⾏する前に 状態を調べることは有⽤だった

v11以降,リクエストがサーバーに 送信されるまでREAD WRITEは

保留されるようになったのでこれで良い

毎回のアップグレード後に必ずチェックするべき項⽬のひとつ

何年も開いていない汎⽤コードは腐った⾷品と同じ: 捨てるか運を天に任せるか

汎⽤コードがまとめられたコンポーネントも忘れずにチェックすること

kill good old generic, you can

respect the name, you should

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod"+<>myLogin+"_"+string(<>customerID))

respect the name, you should

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod"+<>myLogin+"_"+string(<>customerID))

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod"+<>myLogin+"_"+string(<>customerID))

respect the name, you should

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod"+<>myLogin+"_"+string(<>customerID))

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod"+<>myLogin+"_"+string(<>customerID))

プロセス名は容器ではありません

respect the name, you should

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod"+<>myLogin+"_"+string(<>customerID))

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod";<>myLogin;<>customerID)

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod"+<>myLogin+"_"+string(<>customerID))

プロセス名は容器ではありません

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod";<>myLogin;<>customerID)

respect the name, you should

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod"+<>myLogin+"_"+string(<>customerID))

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod";<>myLogin;<>customerID)

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod"+<>myLogin+"_"+string(<>customerID))

プロセス名は容器ではありません

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod";<>myLogin;<>customerID)

パラメーター群をサーバーに転送明快なプロセス名

respect the name, you should

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod"+<>myLogin+"_"+string(<>customerID))

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod";<>myLogin;<>customerID)

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod"+<>myLogin+"_"+string(<>customerID))

プロセス名は容器ではありません

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod";<>myLogin;<>customerID)

パラメーター群をサーバーに転送明快なプロセス名

奇妙または気まぐれに考案された名前では将来のログ解析が困難に

respect the name, you should

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod"+<>myLogin+"_"+string(<>customerID))

$ID_Process:=Execute on server("MySrvProcessMethod";0;"MySrvProcessMethod";<>myLogin;<>customerID)

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod"+<>myLogin+"_"+string(<>customerID))

プロセス名は容器ではありません

$ID_Process:=New process("MyProcessMethod";0;"MyProcessMethod";<>myLogin;<>customerID)

パラメーター群をサーバーに転送明快なプロセス名

奇妙または気まぐれに考案された名前では将来のログ解析が困難に

今⾵に,コンテキスト情報はオブジェクト1個で渡せば良い

respect the name, you should

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while

"Execute on server" メソッドに引数を渡せば良い brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while

"Execute on server" メソッドに引数を渡せば良い

1回にまとめられる

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while

"Execute on server" メソッドに引数を渡せば良い

1回にまとめられる

"息継ぎ"する時間がない

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while

"Execute on server" メソッドに引数を渡せば良い

1回にまとめられる

"息継ぎ"する時間がない

パラメーターをコマンドに直接 渡すことは避けたほうが良い

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while //myReallyOptimizedMethodSrv

$customer_ID:=$1 // 結果を計算する $result:=.... $0:=$result

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while //myReallyOptimizedMethodSrv

$customer_ID:=$1 // 結果を計算する $result:=.... $0:=$result

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while //myReallyOptimizedMethodSrv

$customer_ID:=$1 // 結果を計算する $result:=.... $0:=$result

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while //myReallyOptimizedMethodSrv

$customer_ID:=$1 // 結果を計算する $result:=.... $0:=$result

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while //myReallyOptimizedMethodSrv

$customer_ID:=$1 // 結果を計算する $result:=.... $0:=$result

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while //myReallyOptimizedMethodSrv

$customer_ID:=$1 // 結果を計算する $result:=.... $0:=$result

"Execute on server"コマンドは⾮同期コール

brothers but not twins …

$process_srv_id:=Execute on server("myOptimizedMethodSrv";0;"myOptimizedMethodSrv") SET PROCESS VARIABLE($process_srv_id;customer_ID;$1) $calculation_launch:=True SET PROCESS VARIABLE($process_srv_id;calculation_launch;$calculation_launch) $calculation_finished:=False Repeat GET PROCESS VARIABLE($process_srv_id;calculation_finished;$calculation_finished) GET PROCESS VARIABLE($process_srv_id;Result;$Result) Until ($calculation_finished) $calculation_kill:=true SET PROCESS VARIABLE($process_srv_id;calculation_kill;$calculation_kill)

// myOptimizedMethodSrv calculation_launch:=False calculation_finished:=False calculation_kill:=False customer_ID:=0 while( not(calculation_launch)) DELAY PROCESS(Current process;1) End while

// 結果を計算する Result:=....

calculation_finished:=True While (Not(calculation_kill)) DELAY PROCESS(Current process;1) End while //myReallyOptimizedMethodSrv

$customer_ID:=$1 // 結果を計算する $result:=.... $0:=$result

"Execute on server"コマンドは⾮同期コール

"サーバー上で実⾏"メソッド属性は同期コール

brothers but not twins …

it's free, use it!

composite indexes, try you must

筆者がこれまで コンサルティング依頼を

受けたデータベース

composite indexes, try you must

筆者がこれまで コンサルティング依頼を

受けたデータベース

複合インデックスが 活⽤されていた

データベースの割合

composite indexes, try you must

筆者がこれまで コンサルティング依頼を

受けたデータベース

複合インデックスが 活⽤されていた

データベースの割合複合インデックスはクエリや並び替えの速度を劇的に改善する可能性がある

composite indexes, try you must

筆者がこれまで コンサルティング依頼を

受けたデータベース

複合インデックスが 活⽤されていた

データベースの割合複合インデックスはクエリや並び替えの速度を劇的に改善する可能性がある

恩恵にあずかるためにコードを変更する必要はなく, 定義するだけで良い

composite indexes, try you must

indexes are not only automatic

indexes are not only automatic

ポップアップをクリックしてインデックスの種類を選択

indexes are not only automatic

ポップアップをクリックしてインデックスの種類を選択

少し時間を取ってインデックス設定を⾒直せば,全体の速度を向上させられる

indexes are not only automatic

ポップアップをクリックしてインデックスの種類を選択

少し時間を取ってインデックス設定を⾒直せば,全体の速度を向上させられる

クラスターを使⽤すればサイズを⼤幅に節約することができ,特に対価はない

indexes are not only automatic

if no mistake have you made, yet losing you are …

DESCRIBE QUERY EXECUTION(True)

QUERY BY FORMULA([Flight];([Airport]IATA_AirportCode="SFO")\ & ([Flight]UUID_Line=[Line]UUID) & ([Line]UUID_Airport_To=[Airport]UUID))

$path:=Get last query path(Description in text format) SET TEXT TO PASTEBOARD($path)

DESCRIBE QUERY EXECUTION(False)

if no mistake have you made, yet losing you are …

DESCRIBE QUERY EXECUTION(True)

QUERY BY FORMULA([Flight];([Airport]IATA_AirportCode="SFO")\ & ([Flight]UUID_Line=[Line]UUID) & ([Line]UUID_Airport_To=[Airport]UUID))

$path:=Get last query path(Description in text format) SET TEXT TO PASTEBOARD($path)

DESCRIBE QUERY EXECUTION(False)

クエリプランとクエリパスで視点をエンジンルーム内に移動

if no mistake have you made, yet losing you are …

DESCRIBE QUERY EXECUTION(True)

QUERY BY FORMULA([Flight];([Airport]IATA_AirportCode="SFO")\ & ([Flight]UUID_Line=[Line]UUID) & ([Line]UUID_Airport_To=[Airport]UUID))

$path:=Get last query path(Description in text format) SET TEXT TO PASTEBOARD($path)

DESCRIBE QUERY EXECUTION(False)

クエリプランとクエリパスで視点をエンジンルーム内に移動

優れたクエリを書くため,時には直感を働かせることも必要

if no mistake have you made, yet losing you are …

do not reinvent the wheel, a different game you should play

do not reinvent the wheel, a different game you should play

do not reinvent the wheel, a different game you should play

do not reinvent the wheel, a different game you should play

do not reinvent the wheel, a different game you should play

do not reinvent the wheel, a different game you should play

オブジェクトライブラリで時間を節約・デザインを統⼀・アイデアを共有

do not reinvent the wheel, a different game you should play

オブジェクトライブラリで時間を節約・デザインを統⼀・アイデアを共有

ライセンス不要,使⽤に制約なし!

do not reinvent the wheel, a different game you should play

4D helps your progress

4D helps your progress

4D helps your progress

Mr Smith

VAT rate

4D helps your progress

$id_progress:=Progress New Progress SET BUTTON ENABLED ($id_progress;True) Progress SET TITLE ($id_progress;"Update customers";0;"";True) ALL RECORDS([Customer]) $j:=0 $nb:=Records in table([Customer]) While (Not(End selection([Customer]))) & (Not(Progress Stopped ($id_progress))) $j:=$j+1 Progress SET PROGRESS ($id_progress;$j/$nb;[Customer]name)

/// ...

NEXT RECORD([Customer]) End while

Progress QUIT ($id_progress)

Mr Smith

VAT rate

4D helps your progress

$id_progress:=Progress New Progress SET BUTTON ENABLED ($id_progress;True) Progress SET TITLE ($id_progress;"Update customers";0;"";True) ALL RECORDS([Customer]) $j:=0 $nb:=Records in table([Customer]) While (Not(End selection([Customer]))) & (Not(Progress Stopped ($id_progress))) $j:=$j+1 Progress SET PROGRESS ($id_progress;$j/$nb;[Customer]name)

/// ...

NEXT RECORD([Customer]) End while

Progress QUIT ($id_progress)

Mr Smith

VAT rate

$id_progress:=Progress New Progress SET BUTTON ENABLED ($id_progress;True) Progress SET TITLE ($id_progress;"Apply new parameter";0;"";True) ALL RECORDS([Param]) $j:=0 $nb:=Records in table([Param]) While (Not(End selection([Param]))) & (Not(Progress Stopped ($id_progress))) $j:=$j+1 Progress SET PROGRESS ($id_progress;$j/$nb;[Param]name)

/// ...

NEXT RECORD([Param]) End while

Progress QUIT ($id_progress)

4D helps your progress

$id_progress:=Progress New Progress SET BUTTON ENABLED ($id_progress;True) Progress SET TITLE ($id_progress;"Update customers";0;"";True) ALL RECORDS([Customer]) $j:=0 $nb:=Records in table([Customer]) While (Not(End selection([Customer]))) & (Not(Progress Stopped ($id_progress))) $j:=$j+1 Progress SET PROGRESS ($id_progress;$j/$nb;[Customer]name)

/// ...

NEXT RECORD([Customer]) End while

Progress QUIT ($id_progress)

Mr Smith

VAT rate

$id_progress:=Progress New Progress SET BUTTON ENABLED ($id_progress;True) Progress SET TITLE ($id_progress;"Apply new parameter";0;"";True) ALL RECORDS([Param]) $j:=0 $nb:=Records in table([Param]) While (Not(End selection([Param]))) & (Not(Progress Stopped ($id_progress))) $j:=$j+1 Progress SET PROGRESS ($id_progress;$j/$nb;[Param]name)

/// ...

NEXT RECORD([Param]) End while

Progress QUIT ($id_progress)おすすめ:

ループ10回毎にメソッドをコールする

4D helps your progress

don't keep a dog and bark yourself!

don't keep a dog and bark yourself!

C_POINTER($1;$2)C_LONGINT($nb_total)

ARRAY TEXT($_result;0x0000)CLEAR VARIABLE($nb_total)

$nb:=Size of array($1->)For ($i;1;$nb)

If (Length($1->{$i})=0)Else

APPEND TO ARRAY($_result;$1->{$i})$nb_total:=$nb_total+1

End ifEnd for

COPY ARRAY($_result;$2->)

don't keep a dog and bark yourself!

C_POINTER($1;$2)C_LONGINT($nb_total)

ARRAY TEXT($_result;0x0000)CLEAR VARIABLE($nb_total)

$nb:=Size of array($1->)For ($i;1;$nb)

If (Length($1->{$i})=0)Else

APPEND TO ARRAY($_result;$1->{$i})$nb_total:=$nb_total+1

End ifEnd for

COPY ARRAY($_result;$2->)

がんばり過ぎ〜$nb_total:=0

のほうが⾃然なのに

この変数は要らないのでは

$1->{$i}="" よりも 優れているのかなぁ?=0 / Else よりも #0 のほうが

シンプルじゃないの?

don't keep a dog and bark yourself!

Antoine de Saint Exupéry

La perfection est atteinte, non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il n'y a plus rien à retirer.

Wind, Sand and Stars (1939)