發表文章

目前顯示的是有「powerbuilder」標籤的文章

頒獎用程式【分享】

圖片
  頒獎用顯示程式(含原始碼 pbw) 開發工具:Powerbuilder 10.5 版本:2.0.2.6 版本時間:2019/3/5 平台:Windows 下載位置: https://drive.google.com/file/d/1XX8SDzyeHaZxvOAlmmPOmWu4JJP1dkEp/view?usp=sharing 程式說明: 因應公司於大型會場需要頒獎時,能將得獎者名單顯示在會場投射螢幕上,由於公司參加者眾多超過300人,部分獎項得獎者可能多達50人以上,若主持人連續抽出得獎者並說出得獎者名字或編號時,現場吵雜情況下,得獎者會不知道自己已經得獎,因此透過投射螢幕可以把得獎者清單列於畫面上,讓得獎者不會錯過。

在 Powerbuilder 下轉換 UTF-8 文字為 ANSI 文字

圖片
PB10 + 版本 & Pocket Powerbuilder 2.1+ 版本 直接使用 String 就可以轉換 lbl_src = blob ( ls_string1 , encodingutf8! ) ls_string2 = string ( lbl_src , encodingansi!) powerbuilder 9 (含以下版本) 就得借助 Windows API 來完成轉換 首先,你必須宣告外部函數(declare external functions) function ulong MultiByteToWideChar(           ulong CodePage,           ulong dwflags,           ref string lpmultibytestr,           ulong cchmultibyte,           ref blob lpwidecharstr,           ulong cchwidechar ) library "kernel32.dll" function ulong WideCharToMultiByte(           ulong CodePage,           ulong dwFlags,           ref blob lpWideCharStr,           ulong cchWideChar,           ref string lpMultiByteStr,    ...

powerbuilder的TrackBar和ScrollBar對於滑鼠滾輪的處理

powerbuilder 的 TrackBar (vTrackbar / hTrackBar) 與 ScrollBar (vScrollbar / hScrollbar) 的控制上一直以來都少了一根筋,那就是 Mouse Wheel 滑鼠滾輪的事件。 雖然,Trackbar/Scrollbar 在使用時,滑鼠滾輪都可以控制標桿的移動,但是因為沒有對應的事件與通知,所以沒辦法處理滾輪滾動之後的定位值 你可以在 Trackbar/Scrollbar 找到下面事件 moved - 標桿移動後的觸發,但是只限於使用滑鼠按住標桿的移動才會發生。 pageup/pagedown - 當使用滑鼠點擊標桿 兩側 時,標竿會移動一個距離的事件。 lineup/linedown - 當使用鍵盤方向鍵(Arrow Key)控制標桿移動時,會觸發的事件。 但就缺少滑鼠滾輪事件! 此時就可以利用攔截 Windows Message ID 方式處理: 滑鼠滾輪事件 WM_MOUSEWHEEL = 522 此事件會帶 Word 參數 → 0 =向下滾動、1=向上滾動 在 Trackbar/Scrollbar 裡面有個 Other Event,在裡面下判斷,即可以處理 if message.number = 522 then if message.wordparm < 0 then //mouse wheel down st_pos.text = string(vtb_1.position) else //mouse wheel up st_pos.text = string(vtb_1.position) end if end if 那如果要防止使用者使用滑鼠滾動(禁用),就可以在事件返迴 1 ,以防止事件執行: if message.number = 522 then return 1 end if 相對的這個在 DataWindow Control 物件上也適用喔!

[軟體] 會場音樂播放器 arena music player

圖片
這是為了公司春酒/尾牙使用的音樂播放軟體,用 Powerbuilder 10 開發,使用多部筆記型電腦撥放,搭配我自己 自製的混音器 使用。 >> [新版這裡] 這個播放器可以預載 16 軌音樂,與 8 組音效,基本春酒/尾牙流程是足夠了,不過不含影片的播放,因為雖然可以開發MCI Video Player,但是我一直處理不好字幕檔的問題,所以播放軟體我就改成使用 potPlayer 來處理。而這支程式純粹是用來播放多軌音樂的 這播放器的好處是不需要在資料夾內一個一個點擊開啟音樂,然後又要關閉播放器的問題。 每一軌音樂都可以暫停,然後再播放其它音樂,當另一個音樂流程結束,再繼續原本的音樂。 下載程式 https://drive.google.com/file/d/1SpTYKghgKYE_5LFilqQE84szcjejrhIr/view?usp=sharing 本程式由 PB 10 開發,如果你沒有安裝過 PB10 的 Runtime,需先安裝下面 Runtime 包 https://drive.google.com/file/d/1WRlk4h0-W1G0Mzky6iuGAq9LmJbo-8BE/view?usp=sharing (載點失效請留言給我,我再重新上傳 ※URL會變更) 要注意幾點:

powerbuilder send message control

圖片
Powerbuilder 對於視窗形物件的控制比起 C/C++/C#/VB 等開發工具弱勢多了。 但是,Powerbuilder 提供了 Send 函數來彌補對視窗物件的一些細微控制。 其實,它是源自於 Windows 本身對於標準 Windows 物件的控制,它是使用了 Message ID 方式通知物件進形事件動作,而 Powerbuilder 只是順便利用了這個設計而已。 例如:ListView 為人詬病的就是缺了 Scroll 的控制,在資料量大時,一定會超過一個畫面的資料,會跑到畫面之外,此時你只能用滑鼠去 Scroll 或是用滑鼠操作 Scroll bar ,沒有辦法用 Programming 方式控制。 此時,就可以利用 Windows Message 方式發送控制資訊給 Windows物件 來控制: //捲動功能,可適用在ListView、DataWindow、MulitiLine Editor上 //上捲一行 Send(Handle(lv_mylist), 277, 0, 0) //上捲一頁 Send(Handle(lv_mylist), 277, 2, 0) //下捲一行 Send(Handle(lv_mylist), 277, 1, 0) //下捲一頁 Send(Handle(lv_mylist), 277, 3, 0) //像是下面兩種方式都可觸發按鈕Click事件 Send(Handle(Parent), 273, 0, Handle(cb_OK)) cb_OK.TriggerEvent(Clicked!) //最小化 DataWindo w Send(Handle(dw_whatever), 274, 61472, 0) //最大化 DataWindow Send(Handle(dw_whatever), 274, 61488, 0) //一般大小 DataWindow Send(Handle(dw_whatever), 274, 61728, 0)

powerbuilder匯入(讀取)檔案時的注意技巧

圖片
先看看下面一段程式碼: ls_path = "C:\inetpub\ftproot\upload\custOrder.txt" do while FileExists(ls_path)    yield() loop dw_1.importFile(text!,ls_path) // next , processing dw1 row data FileDelete(ls_path) 這是一個讓客戶用FTP上傳檔案後,並讀取檔案內容,處理後便把檔案刪除的作業,邏輯上是合理的,絕大多數的情況下也是沒有問題的。 但是偶爾發生了客戶資料沒有處理的問題,客戶也說明明就上傳成功了,FTP傳輸日誌有出現傳輸成功的指令,但,為什麼卻沒有處理到資料? 這段程式碼持續使用迴圈檢查檔案是否生成,只要檔案出現就進行讀取。 這看起來沒有錯,但是卻常常發生檔案讀出空白或是不完整的情況。 為什麼會這樣? 最大問題出在『時間差』,也就是檔案名稱產生的時間和檔案內容產生的時間有時間差異存在。檔案越大這個問題越明顯! 因為檔案系統會先生成檔案名稱並賦予記憶體指標(檔案內容緩衝區),當檔案指標被應用程式Close時,OS才會把檔案內容緩衝區的內容,寫到磁碟機上。 這個動作是作業系統為了加快檔案處理的速度而設計,緩衝區大小預設為磁碟sector大小,也就是說你的磁碟如果 sector 是 512K ,預設緩衝區就是 512K,若是sector 為 4096K,緩衝區就是 4096K。然而這個緩衝區可以依照應用程式去要求作業系統調整的,基本的原則是sector的倍數。 相關參考: 微軟檔案緩存 、 資料緩存定義 因此,要如何判斷得知檔案是否已經寫入完成,並且可以讀取呢? 目前我測試有兩種方法可以使用: 一、檔案大小法:如果運作的磁碟機 Sector 是 512K,而你非常肯定你的檔案大小絕對不會超過512K,那很好,除了取得檔案名稱外另外加判斷檔案大小,只要取得的檔案大小超過0,就代表檔案已經從緩衝區 Flush或Close 了,這樣就可以讀取了。 ls_path = "C:\inetpub\ftproot\upload\custOrder.txt" do while FileExists...

a problem Read & ReadEx in Powerbuilder 10

Powerbuilder 10 (含)以後的版本,檔案的讀取分為 Read 與 ReadEx 兩個指令,按照說明文件的用法 ReadEx 支援 StreamMode! 讀取每次可以超過 32767 個位元組,並且支援 TextMode! 的讀取模式,算是很好用的;但是這次的問題卻出在使用 LineMode! 開啟檔案 時 PB10 的 Read 這個指令上: 先看看這段程式碼哪裡出了問題,我有純文字一份文件 A.txt (ANSI編碼)內容為: 數據窗口揭秘:未公開的數據窗口事件 (作者:Mark Brown) 到目前為止,PB的數據窗口控件仍是PB眾多控件中功能最強大,最複雜的控件。 數據窗口固有的行為 然後利用下面這段程式碼讀取內容並顯示在 mle_1(MultiLine Editor)上面 integer li_fn string ls_str mle_1.text = "" li_fn = FileOpen("A.txt",LineMode!,Read!) if li_fn > 0 then //逐行讀取並顯示在mle_1上面 do while FileRead (li_fn , ls_str) >= 0 mle_1.text += ls_str +"~r~n" loop FileClose(li_fn) end if mle_1物件上的顯示內容: 數據窗口揭秘:未公開的數據窗口事件 的數據窗口事件 事件 (作者:Mark Brown) ) 到目前為止,PB的數據窗口控件仍是PB眾多控件中功能最強大,最複雜的控件。 件中功能最強大,最複雜的控件。 複雜的控件。 鞳C 數據窗口固有的行為 的行為 發現了嗎?讀取出的內容怪怪的,幾乎每一行後段文字都重複被讀出,導致整個內容大亂。 但是,這段程式碼如果放在 PB6、PB7、PB8、PB9 執行,卻一點問題就沒有。 整個詭異到不行。 但是如果是英數文內容的檔案,不管哪個版本 PB6 or PB10 就完全不會有問題,測試檔案內容如下: calculate the height of the element and divid...

powerbuilder 的邏輯運算函數

powerbuilder 的位元運算能力幾乎同等『沒有』。 但是使用 windows API 又常常遇到許多變數需要邏輯運算過,但是看看目前的 PFC 的邏輯運算效能也不好。 因此突發奇想,把原本 PFC 的邏輯運算改一改,發現也蠻好用的,效能上也有改善。 Function名稱: f_bitoperator 回傳值: unsignedlong 傳遞參數: aul_s1 [unsignedlong][value]、aul_s2 [unsignedlong][value]、as_operator [string][value] /* PFC簡易版兩組數字做邏輯運算 輸入來源:aul_s1 [uLong],aul_s2 [uLong],as_operator [String] as_operator為邏輯運算描述如:"and" , "or" , "xor" , "not"只需要第一組(aul_s1)輸入, aul_s2放0就可以了 返回:運算結果[Long],當參數錯誤返回NULL */ uLong ll_ret boolean lb_s1[32] , lb_s2[32] , lb_u integer li_bit as_operator = lower(trim(as_operator)) //參數檢查 if isnull(aul_s1) or isnull(aul_s2) or isnull(as_operator) then setnull(ll_ret) Return ll_ret end if if as_operator = "" then setnull(ll_ret) Return ll_ret end if //位元轉換 for li_bit = 32 to 1 step -1 if mod(aul_s1 , 2) = 1 then lb_s1[li_bit] = true else lb_s1[li_bit] = false end if aul_s1 = truncate(aul_s1 / ...

匯入 EDI 檔案到 DataStore

在台灣寫程式常常會需要使用到其他公司的資料交換,而大部份的合作夥伴都很多都會使用EDI檔案傳遞,因此處理EDI檔案就成了家常便飯,但有時候又不想要遇到一個專案就要再寫一次,所以幾乎都將它轉成PFC來使用。 上一次提到了 EDI 轉出 Function ,所以這次來看看轉入EDI檔案的 Function怎麼做吧。 Function 名稱: f_edi2ds 回傳值: Long 傳遞參數: ads_dest[datastore][refrence]、as_file[string][readonly]、as_error[string][refrence] /* 將ED文字檔(as_file)I匯入到 DataStore(ads_dest) EDI切割模式依照 dataObject 的 column.limit 訂定的長度 */ Integer li_ColCount,li_Pos,li_Col,li_file Long ll_collimit[],ll_rc,ll_totl,ll_cc,ll_new String ls_colname[],ls_coltype[],ls_data,ls_val,ls_date,ls_time Datetime ldt_1 boolean lb_fin //檔案存在否? IF not FileExists(as_file) THEN Return -1 //DataStore存在否? IF isnull(ads_dest) OR not isValid(ads_dest) THEN Return -1 END IF //欄位存在否? li_ColCount = integer(ads_dest.Describe("datawindow.column.count")) IF li_ColCount <= 0 THEN Return -1 ll_totl = 0 //取得欄位屬性 FOR li_Col=1 TO li_ColCount ls_colname[li_Col] = ads_dest.Describe("#" + string(li_Col) + ".Name") ll_collimit[li_Col] ...

datawindow使用陣列參數傳遞

圖片
如果你的 DataWindow 需要 in 的條件,要注意的是 Datawindow 裡面 SQL 的 in 參數是需要一個陣列型態的參數,所以你必須在指定 DataWindow 參數的時候宣告它為陣列型態: 1、選擇 Design > Retrieval Arguments

programming DLL using C/C++ for Powerbuilder external function

圖片
真的,用PowerBuuilder的人實在太少了,再加上又會寫C語言作為輔助的更是寥寥可數,只好自己用功一點『自學』了。 C語言有很強大的功能,但每種版本的C語言又有許多的不一樣(C、C++、C#、Object C...),真的學起來相當辛苦,如果電腦原理基礎觀念不好,操作C語言可能真的會成為夢饜,雖然C++與C#有許多強大的功能與函式,但是作為可以被『異種』程式語言呼叫的 獨立 函式庫,可能就非常不理想,因此需要以標準的C語言編譯,讓其他程式可以使用就是一個原則(這是我的想法,如果你有不同的意見歡迎提出)。 雖然C語言的原始碼可以跨平台,不過會由於編譯器的不同而有不太一樣的指令方式。 例如, 我的開發環境在Visual Studio 2005 底下,使用到某些C指令就會有所警告,像是: strcpy => strcpy_s strdup => _scrdup 諸如此類,雖然編譯會發生警告,但是還是可以使用。但是以 Visual Studio 的觀點來說,這些都是被列為 不安全 的指令。所以我撰寫的程式碼都是在符合 Visual Studio 環境底下設計的,若你需要使用到原本C語言原始指令,就可能要自行改寫或是參考一下MSDN的說明了。 好了,來說說如何製作一個標準的DLL供 PowerBuilder 使用吧(不一定限定PB,也可以是VB、Delphi之類): 首先,你必須建立一個新的專案(部分C開發環境沒有專案概念,例如:Dev-C,每個檔案都必須自行建立與整理)

在Powerbuilder下使用API執行Ping指令

利用 Windows 現成的 API 來實現這個功能 1.定義需要使用的結構變數 str_wsadata unsignedinteger   version unsignedinteger   highversion character   description[257] character   systemstatus[129] unsignedinteger   maxsockets unsignedinteger   maxupddg string   vendorinfo str_inaddr unsignedlong   s_addr str_ip_option_information character   ttl character   tos character   flags character   optionssize unsignedlong   optionsdata str_icmp_echo_reply unsignedlong   address unsignedlong   status unsignedlong   roundtriptime unsignedlong   datasize unsignedinteger   reserved unsignedlong   ptrdata str_ip_option_information  options character   data[256] 2.定義 External Functions //Open the socket connection. FUNCTION Integer WSAStartup( uint UIVersionRequested, ref str_WSAData...

sizeof in powerbuilder

PowerBuder 開發資料庫應用程式是相當的方便, 但是對於比較低階的資料處理,常常顯得捉襟見肘, 像是有使用到外部 API 時,需要傳遞變數,更多時候都需要一並傳遞該變數的長度, 此時,如果變數是很單純的,例如:char、integer、long 等, 而這些變數長度大致上都可由 help 來查得, 但是對於比較複雜的變數例如 structure 那就真的麻煩了,尤其是 structure 裡面又包 structure, 若是學過 C/C++ 的人都知道裡面有個 sizeof(var) 的函數, 但唯獨在 PowerBuilder 裡面就是沒有, 這也讓開發者真的挫折不少,每次都要自己算。 網路上我找了很久,終於找到可以實用的方法。 所以底下實做一個物件 nvo_sizeof (PB10) 來完成這個 PowerBuilder 所缺少的部份: 1.建立使用者物件 nvo_sizeof 2.將 AutoInstantiate 勾選 3.建立 Instance Variables Private: CONSTANT integer SIZE_BOOLEAN  = 1   // Boolean CONSTANT integer SIZE_CHAR  = 1   // Char CONSTANT integer SIZE_INT  = 2   // Signed integer CONSTANT integer SIZE_UINT  = 2   // Unsigned integer CONSTANT integer SIZE_LONG  = 4   // Signed Long CONSTANT integer SIZE_ULONG  = 4   // Unsigned Long CONSTANT integer SIZE_STRING  = 4   // As...

背景讀取 DataWindow 的方法

很多時候,DataWindow 的設計目的在於監視列表的資料,尤其是會自動定期更新的列表。 譬如說,我有一個紀錄狀態的 Table ,裡面紀錄的狀態一直在改變, 因此,我會需要一個 DataWindow 定時的去 Retrieve 這些紀錄資料,並將它顯示到畫面上, 讓管理人員可以一目了然。 當然,你會說這有什麼困難?用一個 DataWindow 加上 Timer 就可以解決啦! 但如果,這些資料多到螢幕容納不下時會發生什麼事? 如果你設定必需2秒更新一次又會怎麼樣? 事實是,當管理人員下拉(Scroll)該 DataWindow 以便檢視下方被遮住的資料時, 由於 Retrieve 的關係,所以畫面又跳回第一筆 Row 啦!!! 管理人員會落入不勝其擾的拉下又跳回、拉下又跳回的無間地獄了。 也許加大 Timer 間隔是個方法,不過對於資料的即時性就大打折扣了, 尤其是特別重要的資料更是如此,例如即時股票的變化..... 所以需要一點小技巧來達成這樣的運作模式,利用下面的程式碼技巧可以避開 DataWindow 的顯示畫面 reflash 動作: DataStore lds_src Long ll_row , ll_rcount Integer li_col , li_ccount //建立一個資料倉儲並使之與資料視窗的來源物件相同 lds_src = Create DataStore lds_src.DataObject = dw_1.DataStore lds_src.SetTransObject(SQLCA) //由資料倉儲來讀取資料 lds_src.Retrieve() ll_rcount = lds_src.RowCount() li_ccount = integer(dw_1.Object.DataWindow.Column.Count) for ll_row = 1 to ll_rcount   for li_col = 1 to li_ccount     //複製資料蓋掉畫面上的資料     dw_1.Object.Data[ll_row , li_col] = lds_src.Object.Data[ll_row...

Datawindow裡面資料Row的狀態變化

DataWindow 的 Row 在讀取、新增、修改後都有不同的狀態紀錄, 要取得該 Row 狀態只要使用下面這個指令就可以: DWItemStatus ldwi_row ldwi_row = dw_1.GetItemStatus(ll_row , li_column , Primary!)或 ldwi_row = dw_1.GetItemStatus(ll_row , "col_name", Primary!) 上面程式片碼中 li_column 如果為 0 ,代表取得整個 Row 狀態。 DWItemStatus 有四種狀態: New! (新增 row) NewModified! (新增 row 並修改內容) DataModified! (資料內容被修改) NotModified! (沒有任何修改) 但是要注意的是一個 Row 有兩種狀態 Flag (標籤)用來記錄其受影響的目標: Row Flag (影響範圍屬於整列狀態,一列資料只有一個這樣的標籤紀錄) Column Flag (影響範圍為單一欄位,每個欄位都有一個這樣的標籤紀錄) 而各狀態相關的範圍如下: 狀態 受影響標籤 New! Rows NewModified! Rows DataModified! Rows 與 Columns NotModified! Rows 與 Columns

Powerbuilder inet.PostURL用法

目前PB的開發我都是把它當成一個 Remote Client UI, 所以實際上它沒有連接資料庫,而完全是透過Coldfusion的服務頁面完成資料操作, 因此很多時候需要傳遞大量資料時,簡單的 inet.GetURL 函數就變得不好用了, 因此特地研究了inet.PostURL的用法,它的用法在Help上有兩個範例(我有修改過): 第一種 是簡單的呼叫一個頁面,並取得頁面回傳的HTML內容: (請注意 linet 和 n_internetresult 都是必須先建立的物件與類別, 可參考這裡 ) Blob lblb_args String ls_headers , ls_url Long ll_length n_internetresult lir_html inet linet linet = Create inet lir_html = CREATE n_internetresult ls_url = "http://www.mydoamin.com/testpage.cfm" lblb_args = blob("") ll_length = Len(lblb_args) ls_headers = "Content-Length: " + String(ll_length) + "~n~n" linet.PostURL (ls_url, lblb_args, ls_headers, 8080, lir_html) destroy lir_html destroy linet 上面這種方式並沒有傳遞參數,其實效果如同: linet.GetURL("http://www.mydoamin.com:8080/testpage.cfm",lir_html)

Powerbuilder如何建立網際網路服務

圖片
PowerBuilder 要建立網路服務,基本上需要兩個物件: inet internetResult inet直接建立(instance)就可以了,例如: inet linet linet = Create inet 而接收inet傳回的資料就需要 internetResult 了, 只是這個物件不能直接建立,必須先建立Class (類別), 並且寫入處理回傳資料的程式碼(script),再建立(instance)成為物件才能使用:

let's play sound with powerbuilder

最近在用PB10做一些觸控裝置的UI(使用者介面,User Interface),雖然是觸控,不過使用起來的UE(user experience)跟 iPhone、iPad實在也差很多,無怪乎用過 iPhone之類的觸控裝至以後對於PC的各類觸控總覺得就是不喜歡。 題外話結束。 在設計這類的句有觸控介面的程式時除了UI要非常易懂、直覺以外,其他的輔助可能就需要那麼一點了。在設計這個CASE的UI時,尤其是數字鍵盤,如若加個語音提示或是導航,也許會減少許多輸入錯誤的機會。 目前PB10尚未支援 .NET ,所以依然使用API設計。 使用方式不困難,因為Windows就有內建一些標準函式可以用了 首先,定義函式呼叫 Function Long auxGetNumDevs() Library "Winmm.dll" Function Long auxSetVolume (Long uDeviceID , Long dwVolume) Library "Winmm.dll" alias for "auxSetVolume" Function Boolean sndPlaySound(ref String lpszSound , Long fuSound ) Library "Winmm.dll" alias for "sndPlaySoundW" 然後幾個基本常數 Constant Long SND_SYNC = 0 Constant Long SND_ASYNC = 1 Constant Long SND_NODEFAULT = 2 Constant Long SND_LOOP = 8 Constant Long SND_NOSTOP = 16 再來就是呼叫方式了,大部分常用的呼叫方式有兩種:同步 或 非同步(Synchronous / Asynchronous) 同步方式:採用同步方式的話,程序本身必須等待聲音檔撥完才能繼續執行。 ls_wav = "c:\piano.wav" sndPlaySound(ls_wav , SND_SYNC) 非同步方式:當聲音檔案播放時,...

將Datawindow資料存出成EDI檔案

PowerBuilder 的 DataWindow 本身可以將資料存成許多種格式,但偏偏就是缺了一種格式--EDI (Eletronic Data Interchange)-- 這種格式在台灣是早期非常普遍的格式,詳見 維基百科 、 經建會-解釋「通關作業XML電子資料交換格式」與EDI格式 ,主要多是公家機關使用,舉凡報稅、金融皆是使用此一格,久而久之就變成了早期台灣電腦最普遍的資料交換檔案格式。 這個格式的特色是每個欄位呈現在文字檔案中都有指定的長度(位元數),各欄位資料之間無分隔符號。所以每個ROW DATA呈現成一串字串,每個ROW字串的長度完全一樣。當然,這種格式的優缺點並非這篇的重點,所以這裡就不討論。 例如: 假設 CSV 格式的資料如下 黃小明,1978/3/2,台中市中山路120號,0922-222-113,15 李大海,1970/12/14台北市忠孝東路三段41號8樓-5,02-12345678,23 而轉成 EDI 格式就可能如此 黃小明19780302台中市中山路120號 0922-222-113 SIMON 15 李大海19701214台北市忠孝東路三段41號8樓-5 02-12345678 DAVID CHAU 23

使用Powerbuilder在EXCEL欄位插入圖片

這是由 calvin 提供的 主要是想把圖片插入EXCEL裡面 可以參考下列片段: string ls_filename1,ls_path1,ls_range //要插入的圖 ls_pic = "c:\sign.bmp" OleObject Loo_Excel Loo_Excel=create oleobject if Loo_Excel.ConnectToNewObject("Excel.Application") <> 0 then messagebox('提示','系統未安裝Excel,無法運行此操作!')   return end if Loo_Excel.Workbooks.Open(ls_filename) //選好要插入的儲存格 Loo_Excel.Application.Range( "M22").Select Loo_Excel.Application.ActiveSheet.Pictures.Insert(ls_pic).Select Loo_Excel.application.ActiveWorkbook.Save() Loo_Excel.Application.ScreenUpdating = True Loo_Excel.Application.workbooks.close() Loo_Excel.DisconnectObject() destroy Loo_Excel 其他的部分都可以依理延伸。