發表文章

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

Powerbuilder夾帶檔案發送郵件的方法

圖片
案例版本:PowerBuilder 6.5 powerbuilder本身有呼叫exchange郵件的能力,所以發送郵件只需要使用內定物件與函數即可達成,但是有許多需要注意的地方,例如附件檔案、郵件內容等等。 先看一下畫面的設計: 收件者欄位是 sle_recipient 主旨是 sle_subject 附加檔案是 lb_1 郵件內容是 mle_notetext

報表使用滑鼠滾輪就會發生問題-PowerBuilder6.5

好吧,我承認我是老古董 powerbuilder 6.5的開發工具我還是在使用的..... <<題外話結束>> 如果你設計的報表在遇到滑鼠滾輪滾動時就會出現『Sybase Inc. Product File發生問題,必須關閉,僅此致歉。』的訊息 請注意兩件事: 一、DataWindow中的Detail Band 高度被設為 0。 二、PBVM60.DLL有問題 解決方式: 一、不要故意設計Detail Band高度為0的報表(我知道有時候這樣設計統計表比較方便)。 二、在datawindow視窗物件事件上禁止滑鼠滾輪動作。但如果遇到報表比較長的就很麻煩。 三、更新pbvm60.dll ,如果你要問我哪裡找,我想可能很難吧,畢竟都是骨董級軟體。 目前我還是有保留,需要的人可以留言給我向我索取,不過不確定100%可用於你的PB6版本。 如果想用盡只滑鼠滾輪的方式處理可以參考另外一篇『 如何在datawindow中禁止使用者使用滑鼠滾輪 』。

如何在datawindow中禁止使用者使用滑鼠滾輪

這不算太難,只要懂點MSDN的人大概都能明白吧 Datawindow視窗物件上的兩個事件都可以用,擇一即可 一、寫在 OTHER EVENT CONSTANT integer WM_MOUSEWHEEL = 522 if message.number = WM_MOUSEWHEEL then    message.processed = True    message.returnvalue = 1 end if 二、新增事件ue_syscommand 並繼承pbm_syscommand CONSTANT integer WM_MOUSEWHEEL = 522 if CommandType = WM_MOUSEWHEEL then    message.processed = True    message.returnvalue = 1 end if 用的原理就是利用截取WINDOWS API 的事件訊息,並由PB物件的事件規則去決定返回值,當API收到指定的值,就會發生對應動作。

JUMPCN網站漫畫下載程式

圖片
上一篇是抓 kukudm 網站的程式,由於該站常改程式碼且不穩定,所以最後停止更新該站的擷取。後來經網友推薦的網站中,大概看了一下 jumpcn 網站比較沒那麼多的"機關",因此決定以此站為抓取對象,直接修改上一次的程式" kukucatch "以便節省開發時間。 下載位置: 按這裡 軟體版本:2.2.1.5 檔案大小:5MB(RAR壓縮) 解壓密碼:無 需要安裝:免安裝 *************************************************************************************************** *2011-08-30*另外網友 Wolfar 提供了他開發的版本,可以到下面網址 http://jumptocatch.blogspot.com/ 他的版本目前有持續更新,建議各位網友可以去看看 ***************************************************************************************************

公司統一編號驗證

國稅局目前網頁上不提供,這是從其他部落格找到的,我稍微修改過。 工具:PowerBuilder 先來看一段驗證公式( 來源:酷!學園 ):

設計DataWindow的好習慣:SQL Plan

圖片
PowerBuiler中的DataWindow就是SQL Result的視覺化物件。在.net中的物件中類似是DataGrid。 當你設計一個 DataWindow 時,很大的機會都會用到 SQL 查詢。 但是很方便的設計工具,不代表你可以有效的使用它。 雖然我這裡的範例使用的是 ASE SQL Server, 而且 SQL 語句都是在 SQL server 上執行的, 但是本質上 SQL 查詢的指令和模式都有很大的雷同, 所以這裡沒有指定是哪一種 SQL Server ,我要提供的只是觀念。

在PowerBuilder下轉換簡繁體中文字

聲明:這是在Windows XP SP3繁體中文版環境底下的方式,不一定適用於英文版外掛繁體中文套件及Windows XP簡體版。 這是PB10的版本,如果你是PB10以下的版本,請注意external function宣告的方式不需要使用";ansi"。 首先宣告 instant 變數 : // 區域語系 Constant    long   LCMAP_TRADITIONAL_CHINESE=67108864 Constant    long   LCMAP_SIMPLIFIED_CHINESE=33554432 // 編碼方式 constant Uint CP_ANSI          = 0         // default to ANSI code page constant Uint CP_OEM           = 1         // default to OEM code page constant Uint CP_MAC           = 2         // MAC code page constant Uint CP_TANSI         = 3         // THREAD ANSI code page  constant Uint CP_SYMB          = 42        // SYMBOL constant Uint CP_WIN874        = 874       // "windows-874" "泰文 (Windows)" constant Uint CP_2022_JP_SJ    = 932       // "iso-2022-jp" "日文 (Shift-JIS)" constant Uint CP_GB2312        = 936       // 簡體中文   (GB2312) constant Uint CP_KR            = 949       // "euc-kr" "韓文" constant Uint CP_BIG5 

網路漫畫下載程式

圖片
這是我自己寫的小程式 謝謝各位關心,本頁由於對象網站抓取異常已經停止更新,原程式已經重新修改並導向新網站抓取漫畫,歡迎各位到 這裡來看看 。 原本,在 阿榮 的網頁裡面看到的 抓線上漫畫的小軟體 後,愛看漫畫的我終於可以免除用網頁看漫畫的痛苦,但是常常遇到 kukudm 網站的問題(改程式碼、主機位置、網頁塞車)的困擾,導致常常下載不了,加上原本作者在當兵無法即時維護,沒辦法之餘,只好把以前拿來分析網頁的程式改寫,做出了這支程式,當然也感謝 榮哥 幫我刊載。 不過,由於 它是PowerBuilder 10 開發的,所以Runtime的部份頗大,主程式約400K,但是Runtimer就大到 13MB了!關於Runtime的檔案我還不知道要如何簡化,盡量把不要的DB connect檔案拿掉了。 提醒您,漫畫雖然好看,但是也要讓眼睛適當休息,畢竟螢幕會比書本對您的眼睛殺傷力更大喔。 廢話不多了,簡單介紹用法吧,有興趣玩的就自行下載去玩。 網頁文章內容圖片來不及更新,所以會與程式畫面有一點點出入 下載位置請點這裡 ,版本:2.0.4.5,RAR壓縮檔,約5MB,解壓後約15MB。沒有密碼。 ※來源網站的漫畫列表暫時關閉不對外開放,因此無法取得列表了。 請找到檔案 kukudm.exe,點擊並執行,主畫面如下:

在 SingleLineEdit 輸入時動態過濾 datawindow 中的資料

圖片
假設有個 Window :: w_main 裡面有兩個物件 SingleLineEdit :: sle_id 和 DataWindow :: dw_1 dw_1裡面有 兩個欄位 id 和 name

Powerbulder 呼叫 Windows API 要注意的地方-字串的傳遞

Windows API 函式(以下簡稱API) PowerBuilder(以下簡稱PB,以下範例使用PB6,PB10因為有UNICODE編碼關係會比較麻煩在此不方便做DEMO)的特性大部分用的人都知道,其缺點就是UI介面太單調、低階操作完全不行(我是指位元組變數運算操作還有I/O控制),但是還好它支援API的呼叫使用。 但是另一個問題又來了,API的呼叫很多參數都牽涉到位元組處理還有定址等太多問題,所以本篇僅針對字串傳遞的問題發響。 關於API傳遞字串,其實會使用的人應該都會注意到一件事情,就是API要求字串傳遞時,通常都是以傳址方式處理,而且通常接下來一個參數就是字串長度的值。

EVENT呼叫的注意事項-Yield的使用

在PowerBuilder中事件的呼叫方式分為2種,『Post』與『Trigger』。 利用Trigger呼叫事件其實就像你在呼叫Function一樣,原本的程序會暫停(推入堆疊),然後執行Trigger的EVENT對象,執行完畢後,再回到(推出堆疊)原程序繼續執行,若是有回傳值,則會隨之回傳。 利用Post呼叫事件,則是將要呼叫的EVENT對象放到該物件的Message Queue(佇列)中 等待被執行 ,原本程序不中斷繼續執行,因此如果你的事件有回傳值,會根本都收不到(因為還沒執行) 以上是PB對事件呼叫的方式(對Function 也可使用Post)。 原本,這樣的描述執行方式是沒有問題的,但卻有的很大的盲點,那就就是 yield() 指令。

DataWindow執行時出現encountered select error錯誤

一般DW如果會跳出這個錯誤,通常是DW中的table定義的欄位長度與SQL執行的欄位長度不符。 如果說有其他原因,也可能是DW與SQL指令搭配不完全。 再者,一般DW執行發生錯誤如果沒有攔截dberror事件,是不會得到SQL error的訊息,然而SQL CODE 2 encountered select error:這種錯誤訊息是DW已經將SQL指令送出執行,在資料庫傳送資料到DW上發生無法處理的錯誤,導致無法繼續(encountered)。 據我的經驗是DW當初"設計"時參照使用的Table,後來因為某些因素做了變更(通常是欄位長度加大),導致DW中記載的欄位長度與實際Table不符合,當資料長度小於DW當初定義的欄位長度時還不會發生問題,但是當資料長度超過DW當初定義欄位的長度時就會出現錯誤。 解決方式: 重新進入設計DW的data source,簡單的變更或是調整一下SQL部分語法,此時DW painter會重新對應資料庫Table欄位資訊。 如果擔心有些版面會因為調整過data source就會被破壞(Regenerate),就只好匯出SRD,直接修改SRD檔案中記載TABLE的COLUMN欄位長度,如:CHAR(10) -> CHAR(30) 。使用這種方式要特別注意,修改的欄位長度最好跟資料庫中的Table欄位長度一致,以免後續有問題又需要DEBUG,反而自找麻煩。

Compute欄位小計異常

圖片
請問一下,為什麼我在這個DW的[總成本小計]後面的COMPUTE欄位(如下圖所示)加入sum( compute_0024 for group 1 ) 但出來的結果卻是 我是很單純的想把COMPUTE_0024加總起來而已!!好怪 ******************************************************************************** 關於Compute的問題,我也遇過幾次,原因不是很清楚,但是有些做過調整後就可以使用了,我提供幾種解決方法你可以各個去試試: compute_0024有Null值,因為某些條件下沒有計算值,我推測是Null值,這個Null值 可能 導致Group1上的compute計算sum值錯誤。解決方式:在compute_0024的公式外面加個if(isnull(xx) , 0 , xx)的判斷,強迫讓Null值的公式出現0值,缺點:畫面上會有"0"值出現。 在Group1上的compute公式中加入isnull判斷sum(if(isnull(compute_0024),0,compute_0024) for group 1),這方法不會有第一點的問題,但是如果是compute_0024值有問題,依然不能解決。 在Group1上的compute公式中 不要直接使用compute_0024這種計算欄位 的值,直接將compute_0024中的公式拿來替代compute_0024,因為經過測試發現計算欄位 有時候 去取得其他計算欄位的值時會有異常值的出現(原因不明,我猜可能是PB內部運算順序導致),因此我發現這樣雖然公式會"落落長"但是比較不會有問題。 Compute欄位的format不要使用預設的這個也是特例問題,雖然系統在不指定下會使用[general],卻有時候會發生計算小數點的錯誤問題,通常這種錯誤都會只發生在小數點下,我的經驗是有時候去TOTAL整數卻會跑出一堆小數點以下的數值,修改過FORMAT後就好了。例如僅需要整數時把FORMAT設定:###0。 以上四點是我這邊解決compute field的經驗,你可以修正試試看。

ProgressBar設計

圖片
說真的,當初在使用PB6.5的時候,常常覺得視覺控制項太少(可能是被VB養成的壞習慣),但是因為PB真的有其獨到MIS快速開發的物件導向功能,所以在設計MIS系統的時候,VB只好被我給秉棄不用了;可是說正格的,有時候視覺控制項卻是在UI的分數中占蠻高的比重的。而今天要設計的ProgressBar也是PB6.5缺少的控制項之一,雖然PB7以上的版本已經有這樣的控制項,不過目前朋友還是在使用PB6.5,所以我還是將它設計出來造福一下人群吧。 要設計ProgressBar並不是什麼難事,包括許多DIY的視覺物件也是,但是難就難在要做好一個完整的物件控制項,考驗設計師對使用者(其它設計師)的操作上手速度(這個應該稱作設計介面):物件功能分明度(A功能與B功能好像類似)、可控制精細度(控制項裡面的物件)、封裝一體性(對控制項裡面的物件控制要如同直接對控制項設定控制般簡單)等等,這部份就會造成程式設計師的極大差異。 好了,廢話結束,進入正題吧。 ProgressBar中文的話應該叫做"處理進度條",既然是處理進度,所以有進度百分比來顯示會比較好一點,如此可以稍微整合一下,設計好的物件控制項,別人在使用時就不需要再去加東加西的了。然而條狀要如何產生呢,簡單的可以用 Line 這個物件就好了,但是Line的特性太少,表現起來太單調,所以我改用了Rectangle(別說你不知道這叫矩形)來設計,因為Rectagle具有FillPattern的樣式,可以創造較為美觀的ProgressBar,所以初步規劃如下: 另外考慮到的一點是當Progress為100%時,rectangle是填滿的狀態,但是若Progress為0%時,則rectangle則為一片空白,這樣設計在某些畫面上會有" 空一塊 "的感覺,並不是很美觀: 因此我們希望對rectangle保留外框,而在適當的進度下改變FillPattern的範圍: 可是,若是注意看rectangle物件的屬性,是無法這樣操作的,也就是說FillPattern只會全部塗滿,但是無法 依照指定範圍 塗滿,所以我們必須另外想辦法處理這樣的問題。其實可以用很簡單的方法解決這個問題。 對,你想到了嗎?就是用兩個rectangle,一個當底僅顯示外框,另一個當BAR;當BAR的rectangle需在當底的recta

TreeView DataWindow設計(二)

圖片
看過 上一篇 的簡單說明後,現在就進行實作了 範例程式 。 ※TreeView DataWindow名稱過長,文中會使用TVDW(大寫)來代表其意義。 ※DataWindow簡稱DW(大寫) ※DataStore簡稱DS(大寫) (一)先來看看程式主畫面: 這個畫面的左半邊是展示用的資料,我這邊的展示設定是某家傳直銷的組織圖,因為這樣的組織圖很容易用來表現樹狀結構的特性,如果你不知道傳直銷組織的話,問一下親朋好友應該會有人解釋得很好(?)吧,傳直銷的組織特性就像是樹狀結構圖,基本上分為上線(通常是推薦人)以及下線(通常是所屬會員或是組織成員);上線如同父節點(Parent),下線如同子項目(Child),所以如果能理解的話應該不難理解畫面左邊的列表意思。 現在的目的就是要如何把這樣的條列資料展現成樹狀組織圖,以供列表或是操作了。 主畫面的右半上方是TVDW的產生示範功能,右半下方則是TVDW本身了。 [產生] :用來產生TVDW的樹狀組織圖,資料來源則是依據主畫面左半邊的資料。 [停止] :由於資料多達300多筆,產生會消耗許多時間,如果想中途停止,只要按這個按鈕就好了。 [刪除] :當你選擇了某個項目節點後,按下此鈕,會將該項目連同下屬所有子項目一並全數刪除。 [預覽列印] :列印時的畫面預覽,用來檢視畫面是否超出紙張定義。 [內部資料檢視] :這算是特殊的功能了,上一篇有提到這個TVDW有個DS在儲存實際樹狀資料屬性,理論上使用者 不需要也不可以 直接檢視或修改該DS內容,這僅是提供程式設計師debug以及理論驗證的用途罷了。 [全部展開] :這個是以最基本的根項目(Root)為展開的動作,展開時各節點全部展開(註一)。 [全部收合] :這個是以最基本的根項目(Root)為收合的動作,收合時各節點全部收合(註一)。 [選擇子項全開] :以選擇的項目下屬項目節點全部展開,展開時各節點全部展開(註一)。 [選擇子項全收] :以選擇的項目下屬項目節點全部收合,收合時各節點全部收合(註一)。 [細部設定變更] :在TVDW產生時會依照某些特性設定值作為基本依據,如果需要更改某些特別屬性可以變更下列屬性質,以達所需要效果,其數值單位為PowerBuilder Unit,特別要注意的是屬性設定必須在TVDW"產生"畫面前進行設定,否則無效: 起始X、起始

TreeView DataWindow設計(ㄧ)

圖片
開發工具:powerbuilder 6.5 雖然powerbuilder 10.5已經提供了TreeView DataWindow的功能了 畫面也是標準的DataWindow介面,感覺上也很好用?(我還沒用過啦)。可是呢,目前公司提供的工具最高也僅到PB10而已,大多數的程式和工具也都是維持在PB6.5的版本;而且許多朋友也是還在使用PB6.5苦撐...唉!公司預算有限嘛!能用且用囉。 這讓我興起想要建立自己的TreeViewDataWindow物件的想法。雖然說powerbuilder本身就有treeView的物件,但是那不是DataWindow的型態,所以列印的話效果都不好,也很難控制。 難怪powerbuilder敢誇海口DataWindow是MIS開發報表最方便的工具。 由於DataWindow由於名稱過長,因此文中如果有遇到DataWindow如果有遇到字樣的可能會以DW表示。 《一》首先,先來了解一下樹狀結構吧,樹狀結構顧名思義,一定跟樹....有關係 XD 如果把它的葉子全部脫光光........ 這樣只剩下之枝幹與枝節,然後再把它右轉90度,是不是很像下面的圖.... 那麼這就是所謂樹狀結構圖了,具有相同性質的"節點",每個節點底下還可以再分更多節點,由於看起來像樹一樣,所以就稱為樹狀結構。當然,如果你要表現成TreeView的話,這樣是不行的,因為treeView比較接近條列式,像是下圖: 比較井然有序,比較條列,大部份若要製作成報表,就要使用此種表現方式的報表比較容易看懂。以上的簡單說明主要牽涉到資料存放的方式,如果你對樹狀結構不夠明瞭,那麼當下面設計TreeView的資料結構時候,你就會很難理解。 《二》了解你的開發工具,雖然學PB的很多人都會使用DataWindow,但是對於DataWindow的運作原理卻不是很熟悉。當然這裡不會介紹DataWindow的原理,而是利用其特性去建構成我們要展現的DataWindow。 這個物件主要是裡用DataWindow的屬性建構,因此主要使用modify這個指令來建構DWO(DataWindow Object)。DataWindow本身可說是一個Paint Container,而這個Container包含了幾個區塊:group、detail、header、fotter、summary,

PB多線程自動排程設計(一)

圖片
多線程的設計主要是為了改進單線程自動排程的 問題 ,因此設計成多線程的執行方式來解決,但由於PowerBuilder本身沒有辦法設計MultiThread,因此改用多程式方(MultiProcess)式來模擬此方法。 既然是MultiProcess,那麼需要2支程式,一支是排程程式(Scahdule runner),與工作執行程式(Work Processor)。 排程程式:屬於獨立運作的程式,其內容相當單純,只負責排程表(Scahdule Table)的掃描(Scan)與執行呼叫(Call),由於本身不需要處理工作,因此沒有被工作延滯的可能性,單純的處理排程表的掃描,也可以減少多餘的程式碼維護。 工作執行程式:被動式程式,裡面會撰寫所有的工作程式碼,此程式可以被多次執行,由於在windows下一支程式可以被多次執行,而且不會互相干擾(這是指程式本身,不包含都在讀取相同資料庫的資料表產生的LOCK),所以利用windows的MultiProcess特性來達成模擬multiThread效果。 呼叫意示圖: 多重呼叫亦試圖: 由上圖看,好像需要寫出很多的WorkProcessor程式,但其實不然,在PB的application的OPEN事件中,可以取得CommandLine參數,該Processor程式只需要將所有工作寫在裡面,然後利用CommadnLine來判斷需要執行哪個工作程式碼即可完成。 呼叫方式: 假設排程程式是app.exe,工作執行程式是proc.exe,當排程掃描到此時該執行A工作時,只需要執行 Run('proc.exe A') 當proc.exe執行時,在其OPEN事件的參數CommandLine即可得到一個字串"A",在使用Choose Case來判定執行的程式碼片段。 當然這樣的程式設計也有它的優缺點 優點:排程、工作獨立分離,不互相干擾時序,運作流暢度高。 缺點:程式維護複雜、錯誤追蹤相當困難。 範例程式下載

PB單線式自動排程程式設計(二)

繼上一篇 PB單線式自動排程程式設計(一) 這篇來談談如何改進上一篇的STACK溢位問題吧。 其實這個方法並不難,但是要有足夠的觀念。 1.在原來的window上增加一個自訂事件ue_process 2.在window的共用變數(Instance variables)增加一個布林值 Boolean ib_busy = false 3.把原本在timer事件中的 程式碼全部移動到 ue_process事件中 4.在ue_process事件中的程式碼(不包含變數定義)開頭加入: ib_busy = true 在程式碼最後加入: ib_busy = false 5.在原本的timer事件中寫下下列程式碼: If ib_busy = false Then post event ue_process() End If 原理是利用旗標變數ib_busy來阻擋事件被觸發,當ue_process被執行時 ib_busy被設定為true,假設此時工作A發生問題時,timer事件的再觸發執行時可以透過ib_busy避免ue_process被觸發,如此ue_process就不會有一直被stack起來的問題。 那為何程式要移至ue_process事件?這是因為程式若移至ue_process事件後該工作被執行時stack指標是處在ue_process上,當clock觸發timer事件時,由於timer事件並無被stack住,所以可以順利的執行,因此不會被擋住,該事件可以被順利處理不會stack起來。 當然此法是可以避免timer觸發事件無法消化的問題導致stack溢位而crash發生,但是卻也沒辦法保證其它工作可以正常執行,因為只要有其中一個工作不正常,整個程式依然處在停擺狀態。 比較好的方式就是利用多執行緒撰寫程式,可惜powerbuilder並非用來設計低階處理的程式工具,因此無法像C/C#班可以設計多執行緒;當然山不轉路轉,不能設計多執行緒,但可以設計多執行程式,所以另一種方法便是利用多程式執行方式達到此效果。

PB單線式自動排程設計(一)

圖片
簡介: 這裡所謂單線式排程程式,意指排程掃描與工作處理程式都寫在同一支程式裡面,由於PowerBuild 6程式本身無法像C#般寫成多執行緒的能力,因此在同時處理許多作業時,都得依照程式碼執行的STACK順序執行,故名為"單線式" 準備與設計: 1.首先必須要有一分工作排程清單,例如每日工作 這樣的資料表結構你可以設計成DataWindow,當然你如果要增加欄位或是功能,都是可以的,不過基本上的結構是如此。 結構中"時"、"分"的欄位是用來比對是否進行工作的時間點,當時間行程到達該時間點時就得進行該工作的執行。 "執行時間"則是代表此工作"被執行完成"的時間點,這個用來判斷該工作是否已經被執行,而不會被重複執行的要件。 "啟用"則是決定該工作是否需要被執行,有的人會以另一種觀點"暫停"來設計。 "工作名稱"顧名思義只是用來顯示的名稱,讓人一目瞭然知道此工作的用途。 "代號"則是代表該工作在程式碼運作時的實際作業。 2.設計視窗: 設計一個window(w_app),並將上述排程DataWindow(dw_1)加入裡面。 另外設計一個MultiLineEdit,用以觀察執行結果。 3.程式碼撰寫: OPEN事件 由於排單位是以"分"為基礎比對單位,故時間的區隔就以"分"為準則,因此在w_app的Open事件中寫入Timer(60),表示以60秒觸發一次Timer事件。 TIMER事件 Long ll_count , ll_row ll_count = dw_1.RowCount() For ll_row = 1 to ll_count // 檢查該工作是否啟用,若不啟用則跳過 If dw_1.GetItemString(ll_row , 'active') <> '1' Then Continue // 檢查當天是否已經被執行過,若執行過者不再被執行 If date(dw_1.GetItemDatetime(ll_row , 'work_time')) >= today() then Con