Showing posts with label TH. Show all posts
Showing posts with label TH. Show all posts

Sunday, June 20, 2010

การกำหนดให้ window ขึ้นเฉพาะในหน้าสุดท้ายใน smartforms

หากเราต้องการให้ windows นั้นออกเฉพาะหน้าสุท้ายของ document ให้เรากำหนดที่ Conditions -> And Additional Event -> เลือกที่ Only After End of Main Window
เพียงแค่นี้ Window นั้นก็ขึ้นเฉพาะหน้าสุดท้ายแล้ว

Monday, May 24, 2010

No Vendor Specified

บางครั้งเมื่อเราเรียกคำสั่ง MESSAGE ใน ABAP แล้วเกิด Message Pop up ขึ้นมาว่า "No Vendor Specified" สาเหตุเป็นเพราะว่าใน SAP System ที่เราใช้อยู่นั้นใน Message Class = '00' => Message Number = '000' ไม่ได้ที่การ Maintain ค่าไว้ ซึ่งมันควรจะเป็น &1&2&3&4&5&6&7&8 นั่นจึงเป็นสาเหตุว่าเมื่อเราเรียกคำสั่ง MESSAGE เช่น
MESSAGE 'No data for selection' TYPE 'S'

จึงเกิดข้อความดังกล่าวขึ้น

วิธีนี้ถ้าเราไม่ต้องการแก้ไข Message Class = '00' ก็ให้ใช้คำสั่ง MESSAGE โดยกำหนด Class ที่ต้องการใช้ไปเลยเช่น
MESSAGE ID 'PN' TYPE 'S' NUMBER 016 WITH 'No data for selection'.

Monday, April 19, 2010

Intalio Introduction

ช่วงนี้กำลังทำ R&D เกี่ยวกับ Intalio เลยขอถือโอกาสเขียน Blog เกี่ยวกับมันซะเลย
ความจริง Intalio นั้นมี product อยู่หลายตัว แต่ตัวที่เรากำลังจะแนะนำนี้เป็นตัวที่ใช้จัดการเกี่ยวกับ Workflow โดยใช้มาตรฐานของ BPM กับ BPEL และ Version ที่ดูอยู่ก็เป็น community ซึ่งเราสามารถหาข้อมูลเกี่ยวกับ Version นี้ได้ใน http://community.intalio.com/
ข้อดีของ Version นี้เลยหลักคือ ฟรี สามารถ Download มาใช้ได้เลย สำหรับการ Download นั้นจะแบ่งออกเป็น 2 ส่วน คือ
  1. Designer การลง Designer นั้นก็แค่เรียก .exe ที่เราโหลดมาแล้วก็คลิก Next ไปเรื่อยๆแค่นั้น ส่วน OS ที่ใช้นั้นเท่าที่ลองมา Windows XP ใช้ได้ดี ส่วน Windows 2000 นั้นไม่เหมาะ
  2. Server การลง Server ก็ไม่มีอะไรมากแค่ Extract ไฟลืออกมาวางที่ไหนก็ได้บนเครื่องจากนั้นก็ Set Java home จากนั้นก็เรียก startup.bat(ลงบน Windows) หรือ startup.sh(ลงบน Linux) ก็ได้
จากนั้นเราก็ลองทำตาม Tutorial ดู ซึ่งใน Community ก็มี Tutorial และ Sample มากมายอยู่
แล้วไว้วันหลังเราจะมาลองอธิบายความสามารถของ Intalio กันมั่งนะ วันนี้เอาแค่ Install ให้ได้ก่อนค่ะ

Tuesday, April 6, 2010

ดึงข้อมูลของ TCode: STAT โดยใช้ ABAP

Transaction STAT เป็น Transaction เพื่อใช้สำหรับวิเคราะห์สถิติการใช้งานโปรแกรมของผู้ใช้งาน โดยข้อมูลที่เก็บนั้นไม่ได้เก็บอยู่ในรูปของตาราง แต่เก็บอยู่ในรูปของไฟล์ ซึ่งถ้าเราต้องการดึงข้อมูลของ Transaction นี้ออกมา เราสามารถทำได้โดยการเลือกใช้ Function Module: SAPWL_STATREC_READ_FILE ดังตัวอย่าง

CALL FUNCTION 'SAPWL_STATREC_READ_FILE'
EXPORTING
READ_CLIENT = CLIENT
READ_END_DATE = ENDDATE
READ_END_TIME = ENDTIME
READ_START_DATE = STARTDATE
READ_START_TIME = STARTTIME
TABLES
V2_NORMAL_RECORDS = V2_NORMAL_RECORDS.

จากตัวอย่างจะเห็นว่าเราดึงข้อมูลใน STAT ไฟล์โดยกำหนดข้อมูลเกี่ยวกับ Client, End Date, End Time, Start Date และ Start Time เป็นเงื่อนไขในการเลือกข้อมูล และหลังจากเรียกฟังก์ชั่นนี้ทำงาน ข้อมูลจะถูกกลับมาที่ Internal Table: V2_NORMAL_RECORDS

Monday, April 5, 2010

วิธีการแก้ไข User Status ในใบสั่งผลิต โดยใช้ ABAP

ในบางครั้งระบบ PP ที่อยู่ใน SAP ได้มีการ Config User Status ขึ้นมาเพื่อเป็นข้อมูลเพิ่มเติมที่ User สามารถระบุได้ ดังงนั้นในบทความนี้เราจะใช้ Function Module "I_CHANGE_STATUS" เพื่อแก้ไขข้อมูลนี้ โดยฟังก์ชั่นนี้ต้องการเพียง Object Number ของใบสั่งผลิต, รหัสสถานะที่ Active อยู่ และรหัสสถานะที่ต้องการให้ Active
ตัวอย่างการใช้ Function มีดังนี้

CALL FUNCTION 'I_CHANGE_STATUS'
EXPORTING
OBJNR = PA_OBJNR "Object Number
ESTAT_INACTIVE = lv_inactive "สถานะที่ Active อยู่ ณ ปัจจุบัน ซึ่งหลังจากรันแล้วจะถูกเปลี่ยนเป็นไม่ Active
ESTAT_ACTIVE = lv_active "สถานะที่ต้องการเซ็ตให้ Active
EXCEPTIONS
CANNOT_UPDATE = 1
OTHERS = 2 .

เรียก BAPI_GOODSMVT_CREATE โดยใช้ PHP

ในบทความนี้เราจะแสดงตัวอย่างของการเรียก BAPI ที่ชื่อ BAPI_GOODSMVT_CREATE ผ่านทางภาษา PHP ก่อนอื่นขออธิบาย BAPI_GOODSMVT_CREATE ก่อน BAPI ตัวนี้ใช้สำหรับสร้าง Material Document จากระบบผ่านนอกผ่านทาง BAPI คล้ายๆกับการทำงานของ Transaction: MB1A, MB1B หรือ MB1C
และทุกครั้งหลังจากเรียนก BAPI ที่กล่าวข้างต้นทำงานแล้ว ไม่พบข้อความผิดพลาด เราจะต้องเรียก BAPI_TRANSACTION_COMMIT เพื่อบันทึกข้อมูลเข้าสู่ระบบจริง แต่หากผลข้อผิดพลาด เราก็สามารถเรียก BAPI_TRANSACTION_ROLLBACK เพื่อดึงข้อมูลย้อนกลับ มาดูตัวอย่างกันดีกว่า

// This function receive refdoc and array of goods movement details
// and return data of material doc, material year and return message
function callissuesap($refdoc, $gmm_detail){

$return = array();

// Create saprfc-instance
$sap = create_connection();

// Import Parameters
$today = date("Ymd");

$header = array();
$header["PSTNG_DATE"] = $today;
$header["DOC_DATE"] = $today;
$header["REF_DOC_NO"] = $refdoc;
$header["HEADER_TXT"] = "";

$code = array();
$code["GM_CODE"] = "03";

$item = array();
$lineitem = array();
foreach ($gmm_detail as $gmm_line) {
$lineitem["ORDERID"] = $gmm_line["orderId"];
$lineitem["MATERIAL"] = $gmm_line["material"];
$lineitem["PLANT"] = $gmm_line["plant"];
$lineitem["STGE_LOC"] = $gmm_line["loc"];
$lineitem["BATCH"] = $gmm_line["batch"];
$lineitem["MOVE_TYPE"] = "261";
$lineitem["ENTRY_QNT"] = $gmm_line["qty"];
$lineitem["ENTRY_UOM"] = $gmm_line["une"];
$item[] = $lineitem;
}

// Call-Function
$result=$sap->callFunction("BAPI_GOODSMVT_CREATE",
array(
array("IMPORT","GOODSMVT_HEADER",$header),
array("IMPORT","GOODSMVT_CODE",$code),
array("EXPORT","MATERIALDOCUMENT",""),
array("EXPORT","MATDOCUMENTYEAR",""),
array("TABLE","GOODSMVT_ITEM",$item),
array("TABLE","RETURN",array())
));

// Call successfull?
if ($sap->getStatus() == SAPRFC_OK) {
$sap->callFunction("BAPI_TRANSACTION_COMMIT",array());
$return["MAT_DOC"] = $result["MATERIALDOCUMENT"];
$return["MAT_DOC_YEAR"] = $result["MATDOCUMENTYEAR"];
$return["RETURN"] = $result["RETURN"];
}
else {
$mess = array();
$messline = array();
$messline["TYPE"] = "E";
$messline["MESSAGE"] = $sap->getStatusTextLong();
$mess[] = $messline;

// $sap->printStatus();
$sap->callFunction("BAPI_TRANSACTION_ROLLBACK",array());
$return["MAT_DOC"] = "";
$return["MAT_DOC_YEAR"] = "";
$return["RETURN"] = $mess;
}
$sap->logoff();

return $return;
}

function create_connection() {
return $sap = new saprfc(array(
"logindata"=>array(
"ASHOST"=>"xxx.xxx.xxx.xxx" // application server
,"SYSNR"=>"xx" // system number
,"CLIENT"=>"xxx" // client
,"USER"=>"xxxxxxxxx" // user
,"PASSWD"=>"xxxxxxxxx" // password
)
,"show_errors"=>false // let class printout errors
,"debug"=>false)) ; // detailed debugging information
}


Information about GM_CODE
GM_Code 01: Goods receipt for purchase order
GM_Code 02: Goods receipt for production order
GM_Code 03: Goods issue
GM_Code 04: Transfer posting
GM_Code 05: Other goods receipts
GM_Code 06: Reversal of goods movements

คุณสามารถอ่านข้อมูลเพิ่มเติมได้ โดยไปที่ TCode: BAPI -> Materials Management -> Inventory Management, Goods Movement, CreateFromData -> Tab Documentation

Friday, April 2, 2010

วิธี การดึงข้อมูล System Status ของ Production Order โดยใช้ ABAP [2]

จากที่กล่าวถึงวิธีแรกไปแล้วเป็นวิธีที่ใช้ Function Module
วิธีที่สองที่จะกล่าวถึงนี้เราจะเขียนวิธีการดึง System Status เองเลย ซึ่งความจริงก็ไม่ยาก เพราะ System Status นั้นจะเก็บอยู่ในตาราง JEST ซึ่งเราก็จะเอา เลขที่ OBJNR ที่เราหาได้จากตาราง AUFK เข้าไปทำการ Query เหมือนกัน

SELECT STAT INACT INTO TABLE it_stat
FROM jest
WHERE OBJNR = wa_aufk-objnr.


ถ้าเราต้องการเฉพาะสถานะที่ Active ก็ให้เราใส่เงื่อนไขดังนี้ เ้ข้าไปตอน Query

INACT = ' '


Completed Code:

DATA: it_stat TYPE TABLE OF JSTAT WITH HEADER LINE,
wa_aufk LIKE aufk.

SELECT SINGLE * FROM AUFK INTO wa_aufk
WHERE AUFNR = 'TEST54'.
IF SY-SUBRC = 0.
SELECT STAT INACT INTO TABLE it_stat
FROM jest
WHERE OBJNR = wa_aufk-objnr.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ELSE.
LOOP AT it_stat.
WRITE:/ it_stat-STAT,
it_stat-INACT.
ENDLOOP.
ENDIF.
ENDIF.


ผลลัพธ์ที่ได้

E0001 X
E0010
I0001 X
I0002
I0010
I0016
I0028
I0115
I0118 X
I0215
I0340 X
I0361
I0369
I0420


จะเห็นว่าผลลัพธ์ที่ได้เหมือนกับวิธีแรกเลย

วิธีการดึงข้อมูล System Status ของ Production Order โดยใช้ ABAP [1]

ในการดึงข้อมูลเกี่ยวกับ Production Order บางครั้งเราต้องการทราบข้อมูลที่อยู่ในส่วนของ System Status ซึ่งวิธีแรกที่เราจะนำเสนอนี้คือการใช้ Function Module: STATUS_READ ดังตัวอย่างต่อไปนี้


CALL FUNCTION 'STATUS_READ'
EXPORTING
* CLIENT = SY-MANDT
objnr = wa_aufk-objnr
* ONLY_ACTIVE = ' '
* IMPORTING
* OBTYP =
* STSMA =
* STONR =
TABLES
STATUS = it_stat
EXCEPTIONS
OBJECT_NOT_FOUND = 1
OTHERS = 2
.


ฟังก์ชั่นนี้ใช้ง่ายมาก ขอเพียงรู้เลขที่ OBJNR ที่เราหาได้จากตาราง AUFK ที่นำ Production Order เข้าไป Query
ผลลัพธ์ที่ได้จะออกมาในรูปของ Internal Table ซึ่งมีโครงสร้างประกอบได้ด้วย STAT: รหัสสถานะ และ INACT: Inactive Flag
ในกรณีที่เราต้องการเฉพาะสถานะที่ Active ให้เราเอา Comment ของ ONLY_ACTIVE ออก และ Assign ค่า "X" ให้

ONLY_ACTIVE = ' X'


Completed Code:

DATA: it_stat TYPE TABLE OF JSTAT WITH HEADER LINE,
wa_aufk LIKE aufk.

SELECT SINGLE * FROM AUFK INTO wa_aufk
WHERE AUFNR = 'TEST54'.
IF SY-SUBRC = 0.
CALL FUNCTION 'STATUS_READ'
EXPORTING
* CLIENT = SY-MANDT
objnr = wa_aufk-objnr
* ONLY_ACTIVE = ' '
* IMPORTING
* OBTYP =
* STSMA =
* STONR =
TABLES
STATUS = it_stat
EXCEPTIONS
OBJECT_NOT_FOUND = 1
OTHERS = 2
.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ELSE.
LOOP AT it_stat.
WRITE:/ it_stat-STAT,
it_stat-INACT.
ENDLOOP.
ENDIF.
ENDIF.


ผลลัพธ์ที่ได้

E0001 X
E0010
I0001 X
I0002
I0010
I0016
I0028
I0115
I0118 X
I0215
I0340 X
I0361
I0369
I0420

วิธีการสร้าง Dynamic Selected ตอนทำ Query

ตัวอย่างนี้เราจะ Query ข้อมูลจากตาราง VBAK โดยกำหนดเงื่อนไขในการเลือกข้อมูลว่าเอาข้อมูลของ Sale Order ที่มี Created Date ในวันที่ 05/01/2005. ส่วน Column ที่เราจะเลือกมาแสดงข้อมูลนั้นเราจะใส่เข้าไปใน Internal Table ชื่อ it_fldtab โดย Internal Table นี้ มีโครงสร้างภายในเก็บเป็น Text เท่านั้น
วิธีการประกาศ Internal Table it_fldtab เป็นดังนี้
DATA: wa_fld(72) TYPE C,
it_fldtab LIKE TABLE OF wa_fld.


จากนั้นให้นำชื่อ Column ที่ต้องการ Select ใส่เข้าไปใน it_fldtab ดังนี้
wa_fld = 'VBELN'.
APPEND wa_fld TO it_fldtab.
wa_fld = 'VBTYP'.
APPEND wa_fld TO it_fldtab.
wa_fld = 'AUDAT'.
APPEND wa_fld TO it_fldtab.


จาก Code ข้างต้น เราเลือก Column ที่ชื่อ VBELN คือ เลขที่ Sale Order, VBTYP คือ ประเภทของเอกสาร, AUDAT คือ วันที่ของเอกสาร
จากนั้นก็ Query ข้อมูลตามเงื่อนไขที่ได้กำหนด
SELECT (it_fldtab) INTO CORRESPONDING FIELDS OF TABLE it_vbak
FROM VBAK WHERE ERDAT = '20050105'.


เมื่อ Query ข้อมูลเสร็จก็ทำการเขียนข้อมูลออกมา
IF SY-SUBRC = 0.
LOOP AT it_vbak.
write:/ it_vbak-vbeln, it_vbak-vbtyp, it_vbak-audat.
ENDLOOP.
ENDIF.


Completed Code:

TABLES: VBAK.
DATA: it_vbak TYPE TABLE OF vbak WITH HEADER LINE,
wa_fld(72) TYPE C,
it_fldtab LIKE TABLE OF wa_fld.
wa_fld = 'VBELN'.
APPEND wa_fld TO it_fldtab.
wa_fld = 'VBTYP'.
APPEND wa_fld TO it_fldtab.
wa_fld = 'AUDAT'.
APPEND wa_fld TO it_fldtab.
SELECT (it_fldtab) INTO CORRESPONDING FIELDS OF TABLE it_vbak
FROM VBAK WHERE ERDAT = '20050105'.
IF SY-SUBRC = 0.
LOOP AT it_vbak.
write:/ it_vbak-vbeln, it_vbak-vbtyp, it_vbak-audat.
ENDLOOP.
ENDIF.

วิธีการเรียกหน้าจอ Standard จาก ABAP Report

วิธีการเรียกหน้าจอ Standard จาก ABAP Report เช่นจาก ABAP Report เมื่อเรา Double Click แล้วให้แสดงหน้าจอของ Sale Order (Transaction VA03) ในกรณีที่บรรทัดที่เรา Double Click นั้นเป็นเลขที่ Sale Order
ขั้นตอนเป็นดังนี้
1. ให้ Select ข้อมูลที่เราต้องการแสดงในหน้าแรกก่อน ในตัวอย่างนี้ขอแสดงข้อมูลเลขที่ Sale Order โดยมีการรับค่าจากหน้าจอเป็น select-options และนำมา Query ในตาราง VBAK จากนั้นให้นำข้อมูลที่ Query ได้มาเขียนออกหน้าจอ
SELECT-OPTIONS s_vbeln for vbak-vbeln.

START-OF-SELECTION.
SELECT * FROM vbak INTO TABLE it_vbak
WHERE vbeln in s_vbeln.
LOOP AT it_vbak.
WRITE:/ it_vbak-vbeln.
HIDE it_vbak.
ENDLOOP.

จะสังเกตเห็นว่าตอนที่เรา WRITE ข้อมูลออกหน้าจอนั้นได้เรียกคำสั่ง HIDE ด้วย ซึ่งคำสั่งนี้จะมีผลเมื่อต้องการให้รายงานของเราสามารถ Drill-Down ได้ โดยใช้คู่กับ Event: AT LINE-SELECTION

2. เราจะใช้ Event: AT LINE-SELECTION. เพื่อให้สามารถ Double Click ได้ จากนั้นให้เรียกคำสั่ง CALL TRANSACTION เพื่อใช้ในการเปิดหน้าจอ Standard
AT LINE-SELECTION.
IF sy-lsind = 1.
SET PARAMETER ID 'AUN' FIELD it_vbak-vbeln.
CALL TRANSACTION 'VA03' AND SKIP FIRST SCREEN.
ENDIF.

จากตัวอย่างเราได้มีการเปิดหน้าจอ โดยก่อนเปิดเราต้อง Set Parameter ID ก่ิ่อน เพราะตอนที่เปิด Transaction ของ Standard นั้น เราจะ Default ค่าของเลขที่ Sale Order ให้แล้วเปิดเลย

Completed Code:

TABLES vbak.

DATA: it_vbak TYPE TABLE OF vbak WITH HEADER LINE.

SELECT-OPTIONS s_vbeln for vbak-vbeln.

START-OF-SELECTION.
SELECT * FROM vbak INTO TABLE it_vbak
WHERE vbeln in s_vbeln.
LOOP AT it_vbak.
WRITE:/ it_vbak-vbeln.
HIDE it_vbak.
ENDLOOP.

AT LINE-SELECTION.
IF sy-lsind = 1.
SET PARAMETER ID 'AUN' FIELD it_vbak-vbeln.
CALL TRANSACTION 'VA03' AND SKIP FIRST SCREEN.
ENDIF.