目录

  • 1. PB使用Microsoft.XMLHttp组件的属性与方法
    • 1-1 使用步骤
    • 1-2 XMLHTTP方法:
    • 1-3 XMLHTTP属性:
    • 1-4 示例:
  • 2. Pb中Window添加鼠标滚轮,控制窗口上下滚动
  • 3. PB从剪贴板取图并保存
    • 3-1 定义结构体
    • 3-2 API定义
    • 3-3 函数调用
  • 4. 接口下载的Txt[超过300M也可]导入DataWindow_备忘
  • 5. 获取文件创建时间、最后修改时间及设置最后修改时间的方法
    • 5-1 将以下内容保存为本地文件n_cst_filetime.sru,然后导入pbl中
    • 5-2 程序中使用实例:
  • 6. PB关闭后台进程
    • 6-1 将以下内容保存为nvo_kill_process.sru , 然后导入pbl
    • 6-2 假如要关闭D:\test.exe,则可以这样结束该进程:
  • 7 自动关闭弹出的消息窗口
  • 8 PB数据窗口字段值的校验 validation Expression表达式
  • 9 PB中label型数据窗口,显示的列数通过代码改动
  • 10 PB中N-Up类型数据窗口各种方式的序号列的添加
    • 10-1 序号先从左到右显示,再由上及下
    • 10-2 序号先由上及下,再从左到右
  • 11 PB程序中自动注册OCX控件
  • 12 PB借助adobe reader实现后台自动打印pdf文件
  • 13 PB校验XML是否是合法
  • 14 PB数据窗口风格的判定
  • 15 DW数据窗口常用技巧
  • 16 数据窗口中获得数据(含批量获取
  • 17 修改VSS 默认登录用户名三种方法
  • 18 PB的一些资源下载,含安装包补丁之类

1. PB使用Microsoft.XMLHttp组件的属性与方法

1-1 使用步骤

  1. 创建XMLHTTP对象 //需MSXML4.0支持
  2. 打开与服务端的连接,同时定义指令发送方式,服务网页(URL)和请求权限等。客户端通过Open命令打开与服务端的服务网页的连接。与普
    通HTTP指令传送一样,可以用”GET”方法或”POST”方法指向服务端的服务网页。
  3. 发送指令。
  4. 等待并接收服务端返回的处理结果。
  5. 释放XMLHTTP对象

1-2 XMLHTTP方法:

Open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword )
bstrMethod:  数据传送方式,即GET或POST。 
bstrUrl:     服务网页的URL。 
varAsync:   是否同步执行。缺省为True,即同步执行,但只能在DOM中实施同步执行。用中一般将其置为False,即异步执行。 
bstrUser:    用户名,可省略。 
bstrPassword:用户口令,可省略。 
 
Send(varBody )
varBody:指令集。可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。也可以省略,让指令通过Open方法的URL参数代入。 
 
setRequestHeader( bstrHeader, bstrvalue )
bstrHeader:HTTP 头(header) 
bstrvalue: HTTP 头(header)的值 
如果Open方法定义为POST,可以定义表单方式上传: 
xmlhttp.setRequestHeader( “Content-Type”, “application/x-www-form-urlencoded”)

1-3 XMLHTTP属性:

onreadystatechange:在同步执行方式下获得返回结果的事件句柄。只能在DOM中调用。 
responseBody:   结果返回为无符号整数数组。 
responseStream:  结果返回为IStream流。 
responseText:   结果返回为字符串。 
responseXML:   结果返回为XML格式数据。

1-4 示例:

Integer      li_ret
String      ls_contenttype ,ls_url ,ls_data ,ls_refmesls_url            = Trim( as_url )
ls_data         = as_data
ls_contenttype = "text/plain"OleObject ole_object
ole_object = Create OleObject
li_ret = ole_object.ConnectToNewObject("Microsoft.XMLHttp") //
If li_ret <> 0 Thenis_error = 'Microsoft.XMLHttp注册失败!'Goto Result_Error;
End Ifole_object.Open ( Upper(as_requestmode) ,ls_url, False)
ole_object.setRequestHeader ("Content-type", ls_contenttype +";charset=utf-8")
ole_object.setRequestHeader('Content-Length',String(Len(ls_data)))
ole_object.setRequestHeader('x-ca-key',is_TransKey )
ole_object.setRequestHeader('x-ca-signature',is_TransSignaTure  )Try ole_object.Send(ls_data)ls_refmes = ole_object.responseText
Catch (Exception e)is_error = '接口交易异常,' + e.getMessage()If Isvalid(ole_object) Then Destroy ole_objectReturn False
Catch (RunTimeError Re)is_error = 'nuo_ybjk_trans.uf_request接口运行时发生异常,' + Re.getMessage()If Isvalid(ole_object) Then Destroy ole_objectReturn False
End TryIf ole_object.Status >= 300 Thenis_error = 'http/https请求失败,'+ls_refmes+',详细原因:' + String(ole_object.StatusText) Goto Result_Error;
End Ifole_object.DisconnectObject()
If Isvalid(ole_object) Then Destroy ole_objectas_ref = ls_refmesReturn True Result_Error:If Isvalid(ole_object) Then Destroy ole_objectReturn False

2. Pb中Window添加鼠标滚轮,控制窗口上下滚动

在窗口的other事件里写以下代码:if message.number = 522 thenif inthigh(wparam) < 0 then Send ( handle(this), 277, 1, 0 )elseSend ( handle(this), 277, 2, 0 )end if
end if注意需要设置窗口的VScrollBar=TRUE

3. PB从剪贴板取图并保存

3-1 定义结构体

type bitmapinfoheader from structurelong bisize  long biwidth  long biheight  integer biplanes  integer bibitcount  long bicompression  long bisizeimage  long bixpelspermeter  long biypelspermeter  long biclrused  long biclrimportant
end typetype bitmapfileheader from structureinteger bftype  long bfsize  integer bfreserved1  integer bfreserved2  long bfoffbits
end typetype bitmapinfo from structurebitmapinfoheader bmiheader  unsignedlong bmicolors[]
end type

3-2 API定义

FUNCTION Boolean OpenClipboard(ULong hWndNewOwner) LIBRARY "user32.dll"
FUNCTION Boolean CloseClipboard() LIBRARY "user32.dll"
FUNCTION ULong GetClipboardData(ulong wFormat) LIBRARY "user32.dll"
FUNCTION ulong IsClipboardFormatAvailable(ulong wFormat) LIBRARY "user32.dll"
FUNCTION ULong GetDesktopWindow() LIBRARY "user32.dll"
FUNCTION ULong GetDC(ULong hWnd) LIBRARY "user32.dll"
FUNCTION ULong CreateCompatibleDC(ULong hdc) LIBRARY "gdi32.dll"
FUNCTION ULong SelectObject(ULong hdc,ULong hgdiobj) LIBRARY "gdi32.dll"
FUNCTION Int GetDIBits(ULong hdc,ULong hbmp,UInt uStartScan,UInt cScanLines,REF Blob lpvBits,REF bitmapinfo lpbi,UInt uUsage) LIBRARY "gdi32.dll"
FUNCTION Int GetDIBits(ULong hdc,ULong hbmp,UInt uStartScan,UInt cScanLines, ULong lpvBits, REF bitmapinfo lpbi, UInt uUsage) LIBRARY "gdi32.dll"
SUBROUTINE CopyBitmapFileHeader(REF Blob Destination, bitmapfileheader Source,Long Length) LIBRARY "kernel32.dll" ALIAS FOR "RtlMoveMemory"
SUBROUTINE CopyBitmapInfo(REF Blob Destination, bitmapinfo Source,Long Length) LIBRARY "kernel32.dll" ALIAS FOR "RtlMoveMemory"
FUNCTION Boolean DeleteDC(ULong hdc) LIBRARY "gdi32.dll"
FUNCTION Int ReleaseDC(ULong hWnd,ULong hdc) LIBRARY "user32.dll"
FUNCTION ULong CreateFile(String lpFileName, ULong dwDesiredAccess, ULong dwShareMode, ULong lpSecurityAttributes, ULong dwCreationDisposition, &
ULong dwFlagsAndAttributes, ULong hTemplateFile ) LIBRARY "kernel32.dll" ALIAS FOR "CreateFileA"
FUNCTION Boolean WriteFile(ULong hFile,Blob lpBuffer,ULong nNumberOfBytesToWrite,REF ULong lpNumberOfBytesWritten, &
ULong lpOverlapped) LIBRARY "kernel32.dll"
FUNCTION Boolean CloseHandle(ULong hObject) LIBRARY "kernel32.dll"

3-3 函数调用

long lul_hBitmap
ulong lul_hdcmem, hdc
//判断剪贴板中的数据是否是BMP数据
constant ulong CF_BITMAP = 2
constant ulong DIB_RGB_COLORS = 0
constant ulong BITMAPTYPE = 19778
if IsClipboardFormatAvailable(CF_BITMAP) <> 1 then return
//(1)开始从剪贴板取数据
OpenClipboard(GetDesktopWindow())
lul_hBitmap = GetClipBoardData(CF_BITMAP)
CloseClipboard()
blob lb
hdc = GetDC(GetDesktopWindow())
lul_hdcmem = CreateCompatibleDC(hdc)
selectobject(lul_hdcmem, lul_hBitmap)
//(2)将取得的内存图片转换位blob数据流
ULong lul_hdc, lul_pixels
Blob lblb_header, lblb_info, lblb_bitmap
BitmapInfo lstr_Info
BitmapFileHeader lstr_Header
IF lul_hBitmap = 0 THEN return
lstr_Info.bmiHeader.biSize = 40
IF GetDIBits(lul_hdcMem, lul_hBitmap, 0, 0, 0, lstr_Info, DIB_RGB_COLORS) <= 0 THEN return
lul_pixels = lstr_Info.bmiHeader.biBitCount
lstr_Info.bmiColors[lul_pixels] = 0
lblb_bitmap = Blob(Space(lstr_Info.bmiHeader.biSizeImage))
// 获取文件信息
GetDIBits(lul_hdcMem, lul_hBitmap, 0, lstr_Info.bmiHeader.biheight, &
lblb_bitmap, lstr_Info, DIB_RGB_COLORS)
// 创建BMP文件头
lstr_Header.bfType = BITMAPTYPE
lstr_Header.bfSize = lstr_Info.bmiHeader.biSizeImage
lstr_Header.bfOffBits = 54 + (lul_pixels * 4)
// 将文件头转换成blob
lblb_header = Blob(Space(14))
CopyBitmapFileHeader(lblb_header, lstr_Header, 14)
// 将文件内容转换为blob
lblb_info = Blob(Space(40 + lul_pixels * 4))
CopyBitmapInfo(lblb_info, lstr_Info, 40 + lul_pixels * 4)
// 整合文件信息
lblb_bitmap = lblb_header + lblb_info + lblb_bitmap
//释放通过GetDC或GetWindowDC所检索出来的公用上下文设备
ReleaseDC(GetDesktopWindow(),hdc)
//删除通过CreteDC或CreateCompatibleDC所创建的上下文设备
DeleteDC(lul_hdcmem)  //(3)取到图片文件后,则开始保存到文件中
if len(lblb_bitmap) <= 0 then  return
CONSTANT ULong INVALID_HANDLE_VALUE = -1
CONSTANT ULong GENERIC_WRITE = 1073741824
CONSTANT ULong FILE_SHARE_WRITE = 2
CONSTANT ULong CREATE_ALWAYS = 2
ULong lul_file, lul_length, lul_written
Boolean lb_rtn
// (创建)打开文件  string ls_path, ls_file
int li_rc
li_rc = GetFileSaveName ( "Select BMP File",  ls_path, ls_file, "bmp",  "bmp Files (*.bmp),*.bmp" , "D:\",  32770)
IF li_rc <> 1 Then RETURN
lul_file = CreateFile(ls_path, GENERIC_WRITE, &
FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0)
IF lul_file = INVALID_HANDLE_VALUE THEN  RETURN
// 写文件
lul_length = Len(lblb_bitmap)
lb_rtn = WriteFile(lul_file, lblb_bitmap, &
lul_length, lul_written, 0)
// 关闭文件
CloseHandle(lul_file)     // 需要保持为jpg格式文件的,可以在将图片保存为bmp格式后,再调用外部dll将bmp转为紧jpg

4. 接口下载的Txt[超过300M也可]导入DataWindow_备忘

//====================================================================
// 函数: nuo_ybjk_trans.uf_trans_filedownload()
//--------------------------------------------------------------------
// 描述: 智慧医保9102文件下载:调用接口交易
//--------------------------------------------------------------------
// 参数:
//  string  as_xmbm
//  string  as_filename
//--------------------------------------------------------------------
// 返回:  boolean
//--------------------------------------------------------------------
// 作者:  Zhaof       日期: 2022年01月23日
//====================================================================
Long            i ,ll_rtn
String      ls_path ,ls_fullName , ls_delFile, ls_Ansi_New ,ls_Err
Blob            lb_data// 数据文件夹
ls_path = GetCurrentDirectory()+"\ybsjpt_data"
If Not FileExists( ls_path ) Then CreateDirectory ( ls_path )// 文件全路径名称
ls_fullName =  ls_path + '\' + as_filename
FileDelete(ls_fullName) // 原来已存在则删除// 接口请求信息
If IsNull(is_TransUrl)  Or Trim(is_TransUrl)     = "" Thenis_Error = "接口请求地址为空!"Return False
End If
If IsNull(is_RequestJson) Or Trim(is_RequestJson)    = "" Thenis_Error = "请求json为空!"Return False
End If
// 下载医保中心的数据
httpClient2.setheader('x-ca-key',is_TransKey )
httpClient2.setheader('x-ca-signature',is_TransSignaTure )
httpClient2.Request(httpClient2.httpPost, is_TransUrl ,is_RequestJson ,True)
lb_data = httpClient2.response.Data
If Len(lb_data) <= 0 Thenis_Error = is_title + httpClient2.response.ErrTextReturn False
End If//        ll_BlobLen = Len(lb_data)
//      ll_rtn = uf_create_file(ls_fullname,lb_data,ls_err)
// 改为工具类写入,上方uf_create_file使用PB内部遍历方式效率太低了 Modifyed By Zhaof 2022-11-08
If Not invo_file.blobtofile( lb_data, ls_fullName )  Thenis_Error = "医保中心返回的数据写入本地失败! 写入路径--" + ls_fullNameReturn False
End If// 解压后的文件名称,先删除已存在的同名文件
If as_xmbm = "3202" Then // 对明细账交易时,医保返回的压缩包解压后为result.txtls_delFile = ls_path + "\result.txt"
Elsels_delFile = Left(ls_fullName,Len(ls_fullName) - 4)
End If
// 删除之前已解压并存在同名的文件 -- 亦是本次压缩包解压后的文件名
FileDelete(ls_delFile)// 文件解压  Add By Zhaof   2022-01-19
//      MyZip_ExtractFileAll( ls_fullname,ls_path )
// 中心返回的ZIP压缩包,使用MyZip解压有时候会失败,现改用uo_pbjson_7z对象解压实现
If Not invo_7z.Extract( ls_fullName , ls_path ,True) Thenis_Error = "中心下载的明细ZIP解压失败!~r~n下载的文件地址: " + ls_fullNameReturn False
End If
//FileDelete(ls_fullname) // 删除压缩包文件【保留,应用后续跟踪调试】
ls_fullName = ls_delFile // 解压后的文件全路径
If Not FileExists(ls_fullName ) Thenis_Error = "医保文件解压缩失败! --" + ls_fullNameReturn False
End If// 有时医保文件下载太大, 将大文本文件,按10M 拆分成多个小文件,
//      再执行Ansi转码写入本地Text,用于DW导入使用   Modified By Zhaof 2022-11-08
Long        ll_SplitCount ,j ,ll_line ,ll_beg ,ll_end ,ll_reprow
String  ls_AnsiData ,ls_SplitPath ,ls_tab ,ls_sql ,lf_ImportPath
nuo_ds  lds_9102_res
ll_SplitCount = invo_file.SplitTextFile( ls_fullName,10 )
If ll_SplitCount <= 0 Thenis_Error = "医保下载的文件拆分失败,无法执行导入!"Return False
End If
For i = 1 To ll_SplitCount// 读取文件中的文本内容 -- 会自动进行编码转换ls_AnsiData = invo_file.StringFromTextFile( ls_fullName + "." + String(i) + ".txt" )FileDelete( ls_fullName + "." + String(i) + ".txt" ) // 读取完成将该拆分文件删除// 写入转码后的 Ansi编码的 Text 文件,用于下方Ds导入使用,解决数据库乱码显示invo_file.Blobtofile( Blob(ls_AnsiData), ls_fullName + "." + String(i) + "Ansi.txt" )
Next// 加载现有的字典目录 ,数据量太大了,屏蔽
//uf_init_zdml( as_xmbm )  // 创建目录表存储,用于导入数据, 并更新至数据库
ls_tab = " ybsjpt_" + as_xmbm
ls_sql = " select * from " + ls_tab +" where 1=0 "
If Not invo_utils.uf_dystore( Sqlca, ls_sql, Ref lds_9102_res) Thenis_Error = "目录下载失败," + invo_utils.is_errGoto Errors;
End If// 遍历每个拆分的Ansi编码的Txt文件,执行数据库导入操作
For j = 1 To ll_SplitCount// 待导入的Ansi编码的拆分Txt文件lf_ImportPath = ls_fullName + "." + String(j) + "Ansi.txt"// 获取总行数ll_line = uf_linecount(lf_ImportPath)ll_beg  = 1If ll_line <= 0 Then Continue;For i = ll_beg To ll_line Step 100ll_end = 100/*step*/ + i - 1If ll_end > ll_line Then ll_end = ll_linell_rtn = lds_9102_res.ImportFile(Text!,lf_ImportPath,i,ll_end)// 数据窗口ImportFile根据返回值获取到的描述信息invo_utils.uf_get_dwimpinfo( ll_rtn,Ref ls_Err )// 填充主键值For ll_reprow = 1 To lds_9102_res.RowCount()lds_9102_res.Object.idxh[ll_reprow] = gf_getMax( Sqlca ,Upper(ls_tab) )Next// 已存在数据处理,尚未Cmmituf_Exist_DataModi( as_xmbm, Ref lds_9102_res ) If ll_rtn > 0 Or ll_rtn = -4/*超长截取*/  ThenIf ll_rtn > 0 Or ll_rtn = -4 Then /*超过4000字符问题,在ds的itemerrr中处理掉,正常提交*/If lds_9102_res.Update() = -1 Thenis_Error  = ls_Err + Sqlca.SQLErrTextRollback Using Sqlca;
//                  Goto Errors;   // 存在Rollback的情况,避免后续数据导入终止,此处不中断处理了ElseCommit Using Sqlca;End If// 疾病下载的数据,导入到本地疾病代码字典表If Not uf_import_jbdmzd( as_xmbm, lds_9102_res ) Then Goto Errors;End IfElseIf IsNull(ls_Err) Then ls_Err = "未知的错误!--导入返回值ll_rtn := " + String(ll_rtn)is_Error = ls_ErrGoto Errors;End IfIf ll_rtn = -4 Theni = i - 100 /*step*/ + lds_9102_res.RowCount() //回到开始的步数,再向前走实际行数End Iflds_9102_res.Reset()Next// 使用完删除该拆分文件FileDelete( lf_ImportPath )
NextIf IsValid( lds_9102_res ) Then Destroy lds_9102_res
Return TrueErrors:
// 交易失败,则自动删除拆分好的文件
For j = 1 To ll_SplitCountlf_ImportPath = ls_fullName + "." + String(j) + "Ansi.txt"FileDelete( lf_ImportPath )
Next
If IsValid( lds_9102_res ) Then Destroy lds_9102_res
Return False

5. 获取文件创建时间、最后修改时间及设置最后修改时间的方法

5-1 将以下内容保存为本地文件n_cst_filetime.sru,然后导入pbl中

$PBExportHeader$n_cst_filetime.sru
$PBExportComments$与文件时间有关的外部函数
forward
global type n_cst_filetime from nonvisualobject
end type
type os_filedatetime from structure within n_cst_filetime
end type
type os_fileopeninfo from structure within n_cst_filetime
end type
type os_finddata from structure within n_cst_filetime
end type
type os_securityattributes from structure within n_cst_filetime
end type
type os_systemtime from structure within n_cst_filetime
end type
end forwardtype os_filedatetime from structureunsignedlong        ul_lowdatetimeunsignedlong        ul_highdatetime
end typetype os_fileopeninfo from structurecharacter        c_lengthcharacter        c_fixed_diskunsignedinteger        ui_dos_errorunsignedinteger        ui_na1unsignedinteger        ui_na2character        c_pathname[128]
end typetype os_finddata from structureunsignedlong        ul_fileattributesos_filedatetime        str_creationtimeos_filedatetime        str_lastaccesstimeos_filedatetime        str_lastwritetimeunsignedlong        ul_filesizehighunsignedlong        ul_filesizelowunsignedlong        ul_reserved0unsignedlong        ul_reserved1character        ch_filename[260]character        ch_alternatefilename[14]
end typetype os_securityattributes from structureunsignedlong        ul_lengthstring        ch_descriptionboolean        b_inherit
end typetype os_systemtime from structureunsignedinteger        ui_wyearunsignedinteger        ui_wmonthunsignedinteger        ui_wdayofweekunsignedinteger        ui_wdayunsignedinteger        ui_whourunsignedinteger        ui_wminuteunsignedinteger        ui_wsecondunsignedinteger        ui_wmilliseconds
end typeglobal type n_cst_filetime from nonvisualobject autoinstantiate
end typetype prototypes
//获得应用程序名用
//Function uint GetModuleFileNameA(ulong hModule,ref string lpFilename,ulong nSize) Library "kernel32.dll" //获取应用程序运行目录//文件操作
Function long FindFirstFileA (ref string filename, ref os_finddata findfiledata) library "kernel32.dll"
Function boolean FindNextFileA (long handle, ref os_finddata findfiledata) library "kernel32.dll"
Function boolean FindClose (long handle) library "kernel32.dll"
Function long    OpenFile (ref string filename, ref os_fileopeninfo of_struct, ulong action) LIBRARY "kernel32.dll"
Function boolean CloseHandle (long file_hand) LIBRARY "kernel32.dll"
Function boolean GetFileTime(long hFile, ref os_filedatetime  lpCreationTime, ref os_filedatetime  lpLastAccessTime, ref os_filedatetime  lpLastWriteTime  )  library "kernel32.dll"
Function boolean FileTimeToSystemTime(ref os_filedatetime lpFileTime, ref os_systemtime lpSystemTime) library "kernel32.dll"
Function boolean FileTimeToLocalFileTime(ref os_filedatetime lpFileTime, ref os_filedatetime lpLocalFileTime) library "kernel32.dll"
Function boolean SetFileTime(long hFile, os_filedatetime  lpCreationTime, os_filedatetime  lpLastAccessTime, os_filedatetime  lpLastWriteTime  )  library "kernel32.dll"
Function boolean SystemTimeToFileTime(os_systemtime lpSystemTime, ref os_filedatetime lpFileTime) library "kernel32.dll"
Function boolean LocalFileTimeToFileTime(ref os_filedatetime lpLocalFileTime, ref os_filedatetime lpFileTime) library "kernel32.dll"
end prototypes
type variables
end variables
forward prototypes
public function integer of_getcreatedatetime (string as_filename, ref datetime adt)
public function integer of_getlastwritedatetime (string as_filename, ref datetime adt)
public function integer of_setlastwritedatetime (string as_filename, datetime adt)
private function integer of_convertfiledatetimetopb (os_filedatetime astr_filetime, ref datetime adt)
private function integer of_convertpbdatetimetofile (datetime adt, ref os_filedatetime astr_filetime)
end prototypes
public function integer of_getcreatedatetime (string as_filename, ref datetime adt);//得到文件创建的时间
long ll_handle
os_finddata    lstr_FindData// Get the file information
ll_handle = FindFirstFileA(as_FileName, lstr_FindData)
If ll_handle <= 0 Then Return -1
FindClose(ll_handle)// Convert the date and time
Return of_ConvertFileDatetimeToPB(lstr_FindData.str_CreationTime, adt)
end functionpublic function integer of_getlastwritedatetime (string as_filename, ref datetime adt);//得到文件最后修改的时间
long    ll_handle
os_finddata    lstr_FindData// Get the file information
ll_handle = FindFirstFileA(as_FileName, lstr_FindData)
If ll_handle <= 0 Then Return -1
FindClose(ll_handle)// Convert the date and time
Return of_ConvertFileDatetimeToPB(lstr_FindData.str_LastWriteTime, adt)
end functionpublic function integer of_setlastwritedatetime (string as_filename, datetime adt);//设置文件最后修改时间
boolean lb_Ret
long ll_handle
os_filedatetime lstr_FileTime, lstr_Empty
os_finddata lstr_FindData
os_fileopeninfo lstr_FileInfo// Get the file information.
// This is required to keep the Last Access date from changing.
// It will be changed by the OpenFile function.
ll_handle = FindFirstFileA(as_FileName, lstr_FindData)
If ll_handle <= 0 Then Return -1
FindClose(ll_handle)// Convert the date and time
If of_ConvertPBDatetimeToFile(adt, lstr_FileTime) < 0 Then Return -1// Set the file structure information
lstr_FileInfo.c_fixed_disk = "~000"
lstr_FileInfo.c_pathname = as_FileName
lstr_FileInfo.c_length = "~142"// Open the file
ll_handle = OpenFile ( as_filename, lstr_FileInfo, 2 )
If ll_handle < 1 Then Return -1lb_Ret = SetFileTime(ll_handle, lstr_Empty, lstr_FindData.str_LastAccessTime, lstr_FileTime)CloseHandle(ll_handle)If lb_Ret ThenReturn 1
ElseReturn -1
End Ifend functionprivate function integer of_convertfiledatetimetopb (os_filedatetime astr_filetime, ref datetime adt);//转换文件系统时间为PB时间
os_filedatetime    lstr_LocalTime
os_systemtime    lstr_SystemTime
If Not FileTimeToLocalFileTime(astr_FileTime, lstr_LocalTime) Then Return -1
If Not FileTimeToSystemTime(lstr_LocalTime, lstr_SystemTime) Then Return -1
adt = datetime(blob(String(lstr_SystemTime.ui_wyear) + "-" + &String(lstr_SystemTime.ui_WMonth) + "-" + &String(lstr_SystemTime.ui_WDay) + ' ' + &String(lstr_SystemTime.ui_wHour) + ":" + &String(lstr_SystemTime.ui_wMinute) + ":" + &String(lstr_SystemTime.ui_wSecond) + ":" + &String(lstr_SystemTime.ui_wMilliseconds)))
Return 1
end functionprivate function integer of_convertpbdatetimetofile (datetime adt, ref os_filedatetime astr_filetime);//转换文件系统时间为PB时间
os_filedatetime    lstr_LocalTime
os_systemtime    lstr_SystemTimelstr_SystemTime.ui_wyear = year(date(adt))
lstr_SystemTime.ui_WMonth = Month(date(adt))
lstr_SystemTime.ui_WDay = Day(date(adt))lstr_SystemTime.ui_wHour = hour(time(adt))
lstr_SystemTime.ui_wMinute = Minute(time(adt))
lstr_SystemTime.ui_wSecond = Second(time(adt))
lstr_SystemTime.ui_wMilliseconds = Long(String(adt, "fff"))If Not SystemTimeToFileTime(lstr_SystemTime, lstr_LocalTime) Then Return -1If Not LocalFileTimeToFileTime(lstr_LocalTime, astr_FileTime) Then Return -1Return 1
end functionon n_cst_filetime.create
call super::create
TriggerEvent( this, "constructor" )
end onon n_cst_filetime.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on

5-2 程序中使用实例:

n_cst_filetime ln
string ls_file = 'C:\Program Files\Sybase\PowerBuilder 9.0\pb90.exe'
datetime ldt_create, ldt_lastwrite
ln.of_getcreatedatetime( ls_file, ldt_create)
ln.of_getlastwritedatetime( ls_file, ldt_lastwrite)
messagebox('提示', '文件【' + ls_file + '】~r~n~r~n创建时间:  ' + string(ldt_create, 'yyyy年mm月dd日, hh:mm:ss.fff') +&'~r~n修改日期:  ' + string(ldt_lastwrite, 'yyyy年mm月dd日, hh:mm:ss.fff') )

6. PB关闭后台进程

6-1 将以下内容保存为nvo_kill_process.sru , 然后导入pbl

$PBExportHeader$nvo_kill_process.sru
forward
global type nvo_kill_process from nonvisualobject
end type
type s_process from structure within nvo_kill_process
end type
end forwardtype s_process from structureunsignedlong        structsizeunsignedlong        usageunsignedlong        processidunsignedlong        defaultheapidunsignedlong        moduleidunsignedlong        threadsunsignedlong        parentprocessidunsignedlong        classbaseunsignedlong        flagscharacter        filename[200]
end typeglobal type nvo_kill_process from nonvisualobject autoinstantiate
end typetype prototypes
Function Long GetCurrentProcessId() Library "kernel32.dll"
Function Long CreateToolhelp32Snapshot(Long Flags,Long ProcessId) Library "kernel32.dll"
Function Integer Process32First(uLong Snapshot,ref s_Process Process) Library "kernel32.dll"
Function Integer Process32Next(uLong Snapshot,ref s_Process Process) Library "kernel32.dll"
Function ulong TerminateProcess(long hProcess,ulong uExitCode) LIBRARY "kernel32.dll"
FUNCTION ulong OpenProcess(ulong  dwDesiredAccess,ulong  bInheritHandle,ulong   dwProcessId)   LIBRARY   "kernel32.dll"   end prototypesforward prototypes
public function integer of_kill_process (string as_pro)
end prototypespublic function integer of_kill_process (string as_pro);s_Process lst_Process //进程结构
String ls_FileName[],ls_CurExeName //最多100个进程,可改进
ulong ln_ProcessID,ln_Snapshot,ln_Circle,ln_Count //,ln_SameCount
string ls_Kill_File
Long ll_PID,ll_PID2IF as_pro='' OR isnull(as_pro) Then Return 1ln_ProcessID = GetCurrentProcessId() //取当前进程的ID if IsNull(ln_ProcessID) or ln_ProcessID<1 then return -1 //出错则返回 ln_Snapshot = CreateToolhelp32Snapshot(2,0) //在堆上创建进程快照 if (ln_Snapshot<1) then return -1 //出错则返回 lst_Process.StructSize = 296 //Win32api的Process结构大小if Process32First(ln_Snapshot,lst_Process)=0 then return -1 //取第一个进程失败则返回
End IFls_Kill_File = lst_Process.FileNameIF pos(lower(as_pro),lower(ls_Kill_File))>0 Then           ll_pid=Long(lst_process.processid)       ll_pid2 = Long(OpenProcess(1,0,ll_PID))//使该进程可读写    TerminateProcess(ll_PID2,1) //Kill Process
End IFif lst_Process.ProcessID=ln_ProcessID then //如果为当前进程,不允许删除ls_CurExeName=lst_Process.FileName
END IFdo while true     //循环取列举的进程名称   if Process32Next(ln_Snapshot,lst_Process)=0 then exit //列举完毕        IF lst_Process.ProcessID=ln_ProcessID Then continue  //如果是当前进程.不执行下述杀除操作.   ls_Kill_File = lst_Process.FileName   IF pos(lower(as_pro),lower(ls_Kill_File))>0 Then       ll_pid=Long(lst_process.processid)   ll_pid2 = Long(OpenProcess(1,0,ll_PID))//使该进程可读写    TerminateProcess(ll_PID2,1) //Kill Process   End IF
loop Return 1end functionon nvo_kill_process.create
call super::create
TriggerEvent( this, "constructor" )
end onon nvo_kill_process.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on

6-2 假如要关闭D:\test.exe,则可以这样结束该进程:

nvo_kill_process ln
ln.of_kill_process("test.exe")

7 自动关闭弹出的消息窗口

//-新建一窗口,上面放置一按钮对象cb_msgcb_msg的click事件代码-
Open('msg','这是一个测试关闭消息窗口的例子')//---在窗口Local external Functions声明以下API函
Function long FindWindowA (String lpClassName , String lpWindowName ) Library "user32.dll"
Function boolean IsWindow (Long hwnd ) Library "user32.dll"//---窗口的open事件代码
Timer(2)//触发关闭消息窗口代码的时间间隔//---Timer事件代码
Ulong  handle
String ls_nullSetNull(ls_null)
//获得该消息窗口的句柄
handle = FindWindowA(ls_null,'msg')//字符串"msg"为消息窗口的标题名称If Iswindow(handle) Then//向WINDOWS发送消息关闭窗口,256为wm_keydown消息的整型值Post(handle,256,13,0)
End If

8 PB数据窗口字段值的校验 validation Expression表达式

比如一个datawindow,有个字段的输入必须非负,
可以在validation expression中输入:
number(gettext())>=0,
在validation message中输入
'不能为负值'

9 PB中label型数据窗口,显示的列数通过代码改动

 ls_columns = "3";dw_1.modify("datawindow.label.columns=" + ls_columns)dw_1.object.datawindow.label.rows = 4     // 指定每页纵向4列,按顺序逐个展示或者dw_1.object.datawindow.label.columns=3     // 主界面显示3列dw_1.object.datawindow.label.rows = 4        // 指定每页纵向4列,按顺序逐个展示

10 PB中N-Up类型数据窗口各种方式的序号列的添加

10-1 序号先从左到右显示,再由上及下

// 增加三个计算列: 计算列的具体expression写法分别为:
<1> xh1:getrow() + 0
<2> xh2:getrow() + 1
<3> xh3:getrow() + 2

效果如下图:

10-2 序号先由上及下,再从左到右

<1> xh1:(getrow() - 1) / long(describe("datawindow.rows_per_detail")) + 1
<2> xh2:1 * ceiling(rowcount() / long(describe("datawindow.rows_per_detail")))  - sign(mod(rowcount(), long(describe("datawindow.rows_per_detail")) )) * (1 - mod(rowcount(), long(describe("datawindow.rows_per_detail")) )) + (getrow() - 1) / long(describe("datawindow.rows_per_detail")) + 1
<3> xh3:2 * ceiling(rowcount() / long(describe("datawindow.rows_per_detail")))  - sign(mod(rowcount(), long(describe("datawindow.rows_per_detail")) )) * (2 - mod(rowcount(), long(describe("datawindow.rows_per_detail")) )) + (getrow() - 1) / long(describe("datawindow.rows_per_detail")) + 1    // 规律就是对应第N栏的序号列的表达式为:
(N - 1) * ceiling(rowcount() / long(describe("datawindow.rows_per_detail")))  - sign(mod(rowcount(), long(describe("datawindow.rows_per_detail")) )) * ((N - 1) - mod(rowcount(), long(describe("datawindow.rows_per_detail")) )) + (getrow() - 1) / long(describe("datawindow.rows_per_detail")) + 1

效果如下图:

11 PB程序中自动注册OCX控件

[1].  如果在程序中使用了OCX控件,在开发阶段,可以使用Windows的程序来注册这个控件,如:
regsvr32 ccrpftv6.ocx
regsvr32 filevw61.ocx
如果取消注册的话:
regsvr32 /u ccrpftv6.ocx
regsvr32 /u filevw61.ocx[2]. 自动注册:
OCX文件中都有一个接口DllRegisterServer,这个接口就是用来注册自身的
1. 声明一个外部函数:
Function long DllRegisterServer() Library "ccrpftv6.ocx"
2. 在程序中进行调用:
DllRegisterServer()[3]. 如果程序中使用了多个OCX,而OCX的注册接口都是DllRegisterServer,可以用alias关键字来解决,如:
Function long DllRegisterServer_ccrptv6() Library "ccrpftv6.ocx" alias for "DllRegisterServer"
Function long DllRegisterServer_filevw61() Library "filevw61.ocx" alias for "DllRegisterServer"
程序中调用:
DllRegisterServer_ccrptv6()
DllRegisterServer_filevw61()[4]. 如果每次运行的时候都去注册,效率不高,只有当控件没有注册的时候进行注册,这样,需要知道控件的CLSID,可以从注册表中查到,注册之前先判断一下十分已经注册,如果没有注册,则进行注册,举例如下:
string ls_temp
integer li_ret
long ll_retli_ret = RegistryGet("HKEY_CLASSES_ROOT/CLSID/{19B7F2D6-1610-11D3-BF30-1AF820524153}/TypeLib", "", RegString!, ls_temp) //{19B7F2D6-1610-11D3-BF30-1AF820524153}是这个控件的CLSID
if li_ret = -1 then        //如果返回-1,说明没有注册ll_ret = DllRegisterServer_ccrptv6()
end ifli_ret = RegistryGet("HKEY_CLASSES_ROOT/CLSID/{E67F7BE6-F682-4254-8CF4-3CCE1EEC0EA5}/TypeLib", "", RegString!, ls_temp)//{19B7F2D6-1610-11D3-BF30-1AF820524153}是这个控件的CLSID
if li_ret = -1 then //如果返回-1,说明没有注册ll_ret = DllRegisterServer_filevw61()
end if

12 PB借助adobe reader实现后台自动打印pdf文件

// 前提是客户机上必须要装有adobe的reader
// 在获取reader的路径后加上 /p /h 加上被打印的pdf的文件全路径即可
// 代码:
string ls_reader_path="c:/program files/abobe/reader 9.0/reader>acrord32 /P /h "
string ls_pdf_path="d:/test.pdf"
string ls_print_path=ls_reader_path+ls_pdf_path
run(ls_print_path)

13 PB校验XML是否是合法

long ll_ret
string ls_xmlstr, ls_err
// 返回值=1表示合法
ll_ret = XMLParseString(ls_xmlstr, ValAlways!, ls_err)
if ll_ret = 1 then dw_1.ImportString(ls_xmlstr)

14 PB数据窗口风格的判定

可通过 DataWindow.Processing 判断 DataWindow 对象的类型,dw的类型如下:0 (Default) Form, group, query, or tabular1 Grid2 Label3 Graph4 Crosstab5 Composite7 RichText
………………等等,具体可自己创建一个相应的类型的Dw,右键Edit Source查看具体的值示例一:
This.Object.Datawindow.Processing = '0'示例二:
String    ls_processing
ls_processing = idw_requestor.Describe("datawindow.Processing")
If ls_processing = "4" Then  // 表示为Crosstab类型的Dwidw_requestor.Modify("DataWindow.Crosstab.StaticMode=Yes")
End If

15 DW数据窗口常用技巧

1、如何让存储文件目录的列,显示图片?
答:选择对应的column的display as picture属性为true
2、如何复制grid类型的所选择的行的数据到系统剪切板?
答:string ls_selected
ls_selected=dw_1.Object.DataWindow.Selected.Data
clipbord(ls_selected)
4、如何设置的DW底色?
修改DW的editsource中改变color的值
5、如何将Grid风格改成自由格式?
修改DW的editsource中processing=1 ,由 1改为0
6、要新建一个表A但风格和现有表格B风格一样,怎么将A表快速设置成表B风格?
复制B表C,在C表的DW中的editsource中将表名和字段名改成A表的,即可
7、如何实现gird风格的datawindow的多栏表头?
答:添加 text到header带区,并设置band属性为foreground保存,edit source 修改text的x和width属性表达式如下:
x="100~t integer(describe('firstcol.x')" width="100~tinteger(describe('lastcol.x')) - integer(describe('firstcol.x')) +integer(describe('lastcol.width'))
8、如何过滤dddw编辑风格的显示值为指定值的记录?
答:dw_1.setfilter("lookupdisplay('column_name')='"+ls_display_value_your+"'")
dw_1.filter()
9、如何设置datawindow的某一列为空?
答:string ls_temp[]
setnull(ls_temp)
dw_1.o b j e c t.columnname.primary.current=ls_temp
10、如何设置datawindow的单双行不同颜色间隔?
答:在detail带区的color属性表达式中写上if(mod (getrow(),2)=1 ,rgb(255,0,0),rgb(0,255,0)),如果是当前行以第三种颜色表示,表达式如下:if(getrow()=current(), rgb(255,0,0),if(mod(getrow(),2)=1 ,rgb(0,0,255),rgb(0,255,0)))
11、如何获取指定名称的datawindowo b j e c t?
答:DWObject ldwo_use,ldwo_abc ldwo_use = dw_1.Object ldwo_abc = ldwo_use.__get_attribute("t_1",FALSE)//t_1为datawindow中text对象的名称
12、如何缩放datawindow的打印大小?
答:dw_1.o b j e c t.datawindow.zoom=150 or dw_1.o b j e c t.datawindow.zoom=75
13、如何在已过滤后的数据基础上对datawindow进行过滤?
答:dw_1.setfilter(dw_1.describe("datawindow.table.filter")+your_join+your_new_filter)
dw_1.filter()
14、如何在datawindow中显示动态时间?
答:建立一个计算域,表达式为string(datetime(today(),now()),'yyyy年mm月dd日 hh点mm分ss秒'),同时设置datawindow的属性dw_1.Object.DataWindow.Timer_Interval=500
15、如何让带用title bar的datawindow控件的标题栏诚活动窗口的颜色?
答:外部函数定义:
funcation logn SetActiveWindow(long hwnd ) Library "user32.dll"
datawindow控件的clicked事件代码:
setactivewindow(handle(this))
16、如何设置datawindow的当前行指示图标?
答:在datawindow中建立一个计算列,expression为'',并将该计算列移动为datawindow的第一个列,在datawindow控件的
rowfocuschanged事件中写入代码:
SetRowFocusIndicator(hand!)或setrowfucsindicator(p_1)//p_1为窗口上的picture控件名
17、如何通过代码打开dddw?
答:定义外部函数引用声明
SUBROUTINE keybd_event( int bVk, int bScan, int dwFlags, int dwExtraInfo) LIBRARY "user32.dll"
代码如下: [constant integer VK_F4 = 115
dw_1.SetFocus()
dw_1.SetColumn( "dept_head_id" ) //设置当前dddw
keybd_event( VK_F4,0,0,0 ) // 按下F4键
keybd_event( VK_F4,0,2,0 ) // 释放F4键
18、如何打印datawindow的内容到文件中?
答: dw_1.o b j e c t.datawindow.print.fileName ="c:/temp.prn"
dw_1.print()
19、如何设置dddw的初始值?
答:dw_1.o b j e c t.columnname.Initial="your_initial_value"
20、如何只显示不同的数据?
答:dw_1.filter("isnull(columnname[-1]) and columnnamecolumnname[-1]")
dw_1.filter()
21、如何让带有title bar的datawindow不可以移动?
答:在datawindow的自定义事件ue_nchittest(pbm_nchittest)中写入如下代码:
return 1
22、如何在N-UP显示风格中建立基于第N栏中的列的计算列?
答:如column有两列,number和price ,并显示为两栏,则第一栏的cost计算列的expression为number*price,第二栏的cost_1计算列的expression为number[1]*price[1]
23、如何清空ddlb或edit.codetable中项目?
答:dw_1.Object.columnname.Values=""
24、如何实现指定的column的字体旋转90度?
答:dw_1.o b j e c t.columnname.font.Escapement ="900"
25、如何获取datawindow的sql代码?
答: 可以通过以下四种方法获取sql代码:
string szselect
szselect=dw_1.describe("datawindow.table.select")
szselect=dw_1.describe("datawindow.table.sqlselect")
szselect=dw_1.describe("datawindow.table.select.attribute")
szselect=dw_1.getsqlselect()
27、如何获取datawindow对象占有的虚拟存储的容量?
答:使用datawindow.storage属性
举例:在datawindow控件的retrieverow事件中,写如如下代码:
long lstorage
lstorage=long(dw_1.o b j e c t.datawindow.storage)
if lstorage>50000 then dbcancel()28、如何连续在同一张纸打印两个数据窗口?
答:dw_1.o b j e c t.datawindow.print.filename="temp.prn"
dw_2.o b j e c t.datawindow.print.filename="temp.prn"
dw_1.print()
dw_2.print()
29、如何设置datawindow分组后每个分组中的记录号?
答:建立一个计算列,expression为 getrow() - first(getrow() for group 1)+1
30、如何实现在datawindow中只有新增的行,才可以编辑?
答:在所有的column的protect属性表达式中写入以下表达式:
if(isrownew(),'0','1')
31、除了循环以外,有没有更好的方法统计数据窗口中处于选中状态的行数?
一般习惯于使用循环来统计数据窗口中处于选中状态的行数,有没有更好的方法?其实此问题在应用上用处不大,讨论一下,活跃一下思维还是有好处的。
方法一: long ll_Selected ll_Selected = long(dw_1.describe("evaluate('sum( if(IsSelected(), 1, 0) for all)',1)"))
方法二: long ll_Selected ll_Selected = long(dw_1.describe("evaluate('count(IsSelected() for all)',1)"))
方法三:upperbound(dw_1.Object.Data.Selected)
32、问:怎么让PB只打印当前记录,是用Free格式制作的数据窗口!
---------------------------------------------------------------
答:
DataStore ldt_temp
long ll_Row , ll_Rows
ll_Rows = dw_XX.Rowcount()
If ll_Rows = 0 Then GoTo the_end
If ll_Rows = 1 Then
dw_XX.Print()
GoTo the_end
End if
dw_XX.SetRedraw(False)
ldt_temp = Create DataStore
ldt_temp.DataObject = dw_XX.DataObject
ll_Row = dw_XX.GetRow()
dw_XX.RowsMove(1 , ll_Rows , Primary! , ldt_temp , 1 , Primary!)
ldt_temp.RowsMove(ll_Row , ll_Row , Primary! , dw_XX , 1 , Primary!)
dw_XX.Print()
dw_XX.RowsMove(1 , 1 , Primary! , ldt_temp , ll_Row , Primary!)
ldt_temp.RowsMove(1 , ll_Rows , Primary! , dw_XX , 1 , Primary!)
Destroy ldt_temp
dw_XX.SetRedraw(True)
the_end:
// 只用将上述脚本拷入到打印部分即可,dw_XX为被打印的free型数据窗口,该方法可保证dw_XX中的数据在打印前后包括sort等属性均不发生任何 改变,但效率较低,不宜用在数据量太大的数据窗口中,当然,考虑到打印本身速度就比较慢,所以3000行数据是可以采用这种方法并让用户接受的。若在同一 窗口上存在与dw_XX共享的grid数据窗口并且与dw_XX同时显示,则需要与dw_one一起SetRedraw()
33、字段如何自动换行的同时且自动高度?
答:将数据窗口中相应列的auto horz scroll 为不选中,选中autosize height 将detail的autosize height选中。在数据窗口retrieve 后调用下面函数即可 uf_set_text(datawindow adw_content,string as_columns,boolean,ab_ignoreblank) /************************************************************* describe: 在数据窗口adw_content中,在as_columns中包含的列中插入空格 args: as_columns 要操作的多个列,列间用逗号隔开
************************************************************
*/ if (not isvalid(adw_content)) or isnull(as_columns) or len(as_columns)as_source then adw_content.setitem(ll_row,ls_column[li_column],as_replaced) end if w_waiting.uf_stepit() next next close(w_waiting) iw_frame.enabled = true return 1
34、如何使dw的列不可移动,不可调整列宽?
答:在datawindow的cilcked事件写 if row=0 then return 1 end if
35.光标跳转到数据窗口的某一行某一列
dw_1.scrolltorow(ll_row) dw_1.setcolumn(ll_column)
36 如何使光标指向每页第一行?
long ll_firstrowonpage=long(dw_1.describe("datawindow.firstrowonpage"))
dw_1.scrolltorow(ll_firstrowonpage)
dw_1.setrow(ll_firstrowonpage)
37. Grid的窗口如何使第一列固定不动?
①选上data OBJECT的HSplitScroll属性 ②在constructor事件中: dw_1.Object.DataWindow.HorizontalScrollSplit=integer(dw_1.describe("#1.width")) //第一列的宽度 ③在scrollhorizontal事件中: int i
if pane = 1 then
i = integer(this.OBJECT.datawindow.horizontalscrollposition2)
if i  0 then
this.OBJECT.datawindow.horizontalScrollPosition = 0
end if
else
i = integer(this.Object.DataWindow.HorizontalScrollSplit)
if i  scrollpos then
this.OBJECT.datawindow.horizontalScrollPosition2 = i
end if
end if
38:如何禁止修改grid数据窗口列宽度
答:在Grid数据窗口的Clicked事件中加入:If row = 0 Then return 1
39:grid数据窗口改变列宽度事件:
event:pbm_lbuttondown,pbm_mousemvoe,pbm_lbuttonup
如果:
pbm_lbuttondown: 在数据窗口标题栏(getrow() = 0 and GetObjectAtPointer =你的标题)按下鼠标左键,记一个标志;
pbm_mousemvoe: 鼠标移动了,在记一个标志;
pbm_lbuttonup: 这时鼠标左键up,再判断最后一列的位置是否发生变化,如果有,写你的脚本。
40:如何判断数据窗口内容是否修改
if dw_wh.deletedcount() + dw_wh.modifiedcount() > 0 then
integer li_ret
li_ret = messagebox("注意","数据已经被修改,是否存盘?",Question!,YesNoCancel!)
41:如何得到数据窗口鼠标光标下的控件和行建立一个自定义事件,事件号pbm_dwnmousemove,   事件有参数row、dwo
42:如何改变GRID数据窗口列位置(新手常见)
先preview,然后在预览窗口拖动位置即可。
070411更新
43:数据窗口循环删除行,必须要从最后一行开始删除,如
for ll_row =dw_1.rowcount() to 1 step -1
//if 删除条件 then
dw_1.deleterow(ll_row)
next
// 当然,也可以用do while 加上 find函数实现

16 数据窗口中获得数据(含批量获取

通过PowerBuilder的数据窗口对象属性,可以指定一定格式的表达式来直接从数据窗口中获得数据
---------------------------------------------------------------------
1) 在知道列或计算域名时得到数据得到某列中一行或全部的值,
表达式:(如果rownum忽略,则可得到缓冲区或数据源的值)
dwcontrol.Object.columnname {.buffer } {.datasource } { [ rownum ] }
其中datasource 参数表示数据源,它有两个可选项,Current(缺省)和Original,由此参数我们可以指定数据是从当前数据窗口上还是从数据库中得到。对于计算域,它不能被改变也没有当前值,所以我们必须指定为此参数为Original。
示例:
缺省设置是在Primary缓冲区的当前值,下面语句是等价的,都是从第一行得到emp_name列的值
dw_1.Object.emp_name[1]
dw_1.Object.emp_name.Primary.Current[1]
下面语句设置emp_name列的第一行值为“国防科技大学先进制造中心”
dw_1.Object.emp_name[1] = "国防科技大学先进制造中心"
下面语句得到所有emp_name列的值,并将它们放入数组中
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Current
下面语句得到emp_name列在filter缓冲区的所有当前值
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Filter
下面语句得到emp_name在filter缓冲区的初始值(数据库中的值)
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Filter.Original
下面语句得到emp_name列在delete缓冲区的第14行的当前值
string ls_name
ls_name = dw_1.Object.emp_name.Delete[14]This statement gets the original
下面语句得到emp_name列在delete缓冲区的第14行的初始值(数据库中的值)
string ls_name
ls_name = dw_1.Object.emp_name.Delete.Original[14]
下面语句得到review_date计算域的所有值
string ld_review[]
ld_review = dw_1.Object.review_date.Original
得到被选择项的值
表达式:dwcontrol.Object.columnname {.Primary }{.datasource }.Selected
示例:
由于Primary缓冲区是程序本选择项所在的唯一缓冲区并且当前数据是缺省的,下面的语句作用是等价的,它们实现从emp_name列中得到被选中行的值。
dw_1.Object.emp_name.Selected
dw_1.Object.emp_name.Primary.Selected
dw_1.Object.emp_name.Current.Selected
dw_1.Object.emp_name.Primary.Current.Selected
下面语句从数据库中得到被选择行的数据
dw_1.Object.emp_name.Original.Selected
dw_1.Object.emp_name.Primary.Original.Selected
下面语句设置emp_name列的第一个被选中行的值为空字符串
string ls_empty[]
ls_empty[1] = ""
dw_1.Object.emp_lname.Selected = ls_empty
下面语句可得到emp_name列被选中行的初始值(从数据库中检索出的值),并将它放入一个字符串数组
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Original.Selected
得到一定范围的值
返回指定列的一个范围的行的值,并将它们放入数组
表达式:
dwcontrol.Object.columnname {.buffer } {.datasource } [ startrownum,
endrownum ]
示例:
由于Primary缓冲区和当前数据是缺省选项,下面的语句式等价的
dw_1.Object.emp_name[11,20]
dw_1.Object.emp_name.Primary[11,20]
dw_1.Object.emp_name.Current[11,20]
dw_1.Object.emp_name.Primary.Current[11,20]
下面语句将emp_name列从11行到20行的值设置为空字符串
string ls_empty[]
ls_empty[1] = ""
dw_1.Object.emp_name[11,20] = & {"","","","","","","","","",""}
---------------------------------------------------------------------
下面语句的得到emp_name列的初始值,并将它们放入一个字符串数组
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Original[11,20]
---------------------------------------------------------------------
下面语句得到emp_name列在过滤缓冲区从5行到8行的当前值,并且将它们放入到数组中
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Filter[5,8]
---------------------------------------------------------------------
下面语句得到emp_name列在过滤缓冲区从5行到8行的初始值,并且将它们放入到数组中
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Filter.Original[5,8]
---------------------------------------------------------------------
下面语句得到emp_name列在删除缓冲区从50行到200行的当前值,并且将它们放入到数组中
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Delete[50,200]
---------------------------------------------------------------------
下面语句得到emp_name列在删除缓冲区从50行到200行的初始值,并且将它们放入到数组中
string ls_namearray[]
ls_namearray = dw_1.Object.emp_name.Delete.Original[50,200]
---------------------------------------------------------------------2)得到已知列号列的值
得到指定行号列号的值
表达式:
dwcontrol.Object.Data {.buffer } {.datasource } [ rownum, colnum ]
示例:
由于Primary缓冲区和当前值选项是缺省的,所以下面语句式等价的,都是得到第一行,第二列的数据
dw_1.Object.Data[1,2]
dw_1.Object.Data.Primary.Current[1,2]
---------------------------------------------------------------------
下面语句将Filter缓冲区的初始值中得第一行,第二列的值改为0
dw_1.Object.Data.Filter.Original[1,2] = 0
---------------------------------------------------------------------
得到一定范围行的数据
表达式:
dwcontrol.Object.Data {.buffer } {.datasource } [ startrownum, startcolnum, endrownum, endcolnum ]
示例:
---------------------------------------------------------------------
由于Primary缓冲区和当前值选项是缺省的,所以下面语句式等价的,都是得到第一行到第十行,第一列到第四列的值
dw_1.Object.Data[1,1,10,4]
dw_1.Object.Data.Primary.Current[1,1,10,4]
---------------------------------------------------------------------
下面语句得到employee Ids和 last names列在delete缓冲区的所有行的值,Ids和names列是第一第二列。得到的数据放在名为str_namelist的一个结构中,此结构有两个属性,整形的id和字符串形的lastname。Ids和names被存放在文件deleted.txt中。
integer li_fileNum
long ll_deletedrows
str_namelist lstr_namelist[]
ll_deletedrows = dw_1.DeletedCount()
lstr_namelist = &
dw_1.Object.Data.Delete[1,1, ll_deletedrows,2]
li_fileNum = FileOpen("C:\HR\DELETED.TXT", &
LineMode!, Write!)
FOR ll_count = 1 to UpperBound(lstr_namelist)
FileWrite(li_fileNum, &
String(lstr_namelist.id) + &
" " + &
lstr_namelist.lastname + &
"~r~n")
NEXT
FileClose(li_fileNum)
---------------------------------------------------------------------
下面的语句使Ids和last names列的数据为NULL
long ll_n
str_namelist lstr_namelist[]
SetNull(lstr_namelist[1].id)
SetNull(lstr_namelist[1].lastname)
FOR ll_n = 2 to dw_1.RowCount()
lstr_namelist[ll_n] = lstr_namelist[1]
NEXT
dw_1.Object.Data[1,1, dw_1.RowCount(),2] = lstr_data3)得到整行数据
得到数据窗口上的某行或全部行的数据
表达式:
dwcontrol.Object.Data {.buffer } {.datasource } { [ rownum ] }
示例:
---------------------------------------------------------------------
由于Primary缓冲区和当前值选项是缺省的,所以下面语句式等价的,都是得到Primary缓冲区第五行的当前数据
dw_1.Object.Data[5]
dw_1.Object.Data.Primary.Current[5]
下面语句将数据窗口Primary缓冲区的当前值放入到一个结构数组中
any la_dwdata
la_dwdata = dw_1.Object.Data
下面语句得到数据窗口Delete缓冲区的当前值,并将它放入到一个结构数组中
any la_dwdata
la_dwdata = dw_1.Object.Data.Delete
下面语句用数据窗口dw_2的Primary缓冲区的当前值覆盖嵌套报表的第二行的数据,在数据窗口dw_2中的列必须与嵌套报表中的列相同:
dw_1.Object.NestRep[2].Object.Data = dw_2.Object.Data
---------------------------------------------------------------------
得到选中行的数据
表达式:
dwcontrol.Object.Data {.Primary } {.datasource } .Selected
示例:
由于Primary缓冲区和当前值选项是缺省的,所以下面语句式等价的,都是得到选中行的数据
dw_1.Object.Data.Selected
dw_1.Object.Data.Primary.Selected
dw_1.Object.Data.Current.Selected
dw_1.Object.Data.Primary.Current.Selected
=====================================================================
下面语句得到被选中行的初始值
dw_1.Object.Data.Original.Selected
dw_1.Object.Data.Primary.Original.Selected
---------------------------------------------------------------------
下面语句得到dw_2中Primary缓冲区选中行的当前值,然后放到dw_1中的列useroption(下拉数据窗口)中
dw_1.Object.useroptions.Object.Data = dw_2.Object.Data.Selected4)从Crosstab数据窗口中获得点击域名和域值
对于Crosstab类型的数据窗口,我们在前面已做了简要的介绍,但由于它的行列都可以随着后台数据库存放数据的改变而发生改变,所以在想得到它的某个行列定义的值时不能采用一般的方法,如GetItem××××和点操作符。
通过数据窗口画板可以看到所有的列具有同样的列名,在程序运行时它们会自动的*列名后加后缀的方法进行区别,格式为:列名_列号~t行号,列号和行号之间通过‘~t’分隔,列名和列号通过‘_’分隔。因此如果我们需要detail栏的任何一列的值,就需要将得到的信息进行解析,提取出选择的列名,列号和行号,然后才可以通过一般得数据的方法在数据窗口中获得需要的数据。下面我们以一个具体的例子来解说上面采用的方法。
作用:在数据窗口(数据源为Crosstab)的Cliked事件中编程,当点击事件发生后将获得点击交*表行列交叉点的值;
程序:
//定义变量
string ls_detail, ls_name, ls_col
int li_pos, li_len, li_row, li_col
//判断用户点击处是否为detail栏,如不是则退出
if left(getbandatpointer(),6) <> "detail" then return
//得到点击域的信息
ls_detail = geto b j e c tatpointer()
//得到detail栏第二列的名称,第一列为数据窗口行信息
ls_name = Object.#2.Name
//将第二列列名和前面点击得到的点击域信息进行比较,如不是点击的第二列则退出
if left(ls_detail,len(ls_name)) <> ls_name then return
//得到点击域的行号
li_row = row
li_len = len(ls_detail)
//从前面得到点击域信息中得到关于列号的信息
ls_col = right(ls_detail, li_len - len(ls_name))
//得到点击域的列号if left(ls_col,1) <> "_" then
li_col = 2
else
li_pos = pos(ls_col,"~t")
li_col = integer(mid(ls_col,2,li_pos - 1) ) + 2
end if
//显示出点击域的值
string(getitemnumber(li_row,li_col))

17 修改VSS 默认登录用户名三种方法

可用以下任一个方法修改这个默认名字,三个方法的做优先级依次递增。一个以上的方法同时使用时,优先级最高的有效。一、修改 Window 用户名、或数据库中的用户名使之匹配保持勾选“Use network name for automatic user log in”这个最不方便,不推荐二、使用系统环境变量  【推荐】桌面上右键点“我的电脑”,依次选“属性-高级-环境变量”新建一个系统环境变量 SSUSER,变量值改为希望登录的用户名这个方法相对于后面使用快捷方式的好处是VSS集成到开发环境中仍然有效。也可以添加密码SSPWD,变量值改为希望登录的密码  三、使用快捷方式参数右键点 Microsoft Visual SourceSafe 6.0 启动的快捷方式,属性,修改目标栏用 -y 参数输入用户名和密码(无密码的可以只输入和用户名最方便,可随时修改(用这个方法还可以通过多个快捷方式登录不同权限的用户),推荐。"D:\Program Files\Microsoft Visual SourceSafe\ssexp.exe" -yMyName, passowrd图中的 MyName 是用户名(前面的 -y 不能省略,要和用户名挨在一起),passowrd 是密码,中间用逗号隔开(密码为空时省略逗号和password)。所以最好同时使用二、三两种方式,无论是桌面启动,不是集成到开发环境启动都有效。

18 PB的一些资源下载,含安装包补丁之类

链接地址,点击跳转

PowerBuilder/PB常用备忘相关推荐

  1. office 软件常用备忘(删除线/冻结等)

    office 软件常用备忘(删除线/冻结等) Word: 1 大纲显示/navigation display: 视图/View --> Navigation Pane (left) 2 Trac ...

  2. Android 常用备忘

    键盘相关 显示键盘 InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT ...

  3. iOS项目_常用备忘

    打开图片的触摸 eImageView.isUserInteractionEnabled = true // 隐藏键盘: eInputField.becomeFirstResponder() //自动弹 ...

  4. Webstorm常用快捷键备忘(Webstorm入门指南)

    WebStorm 是jetbrains公司旗下一款JavaScript 开发工具.被广大中国JS开发者誉为"Web前端开发神器"."最强大的HTML5编辑器". ...

  5. T-SQL备忘(6):常用内置函数

    T-SQL备忘(6):常用内置函数 日期和时间函数: 1.获取当前时间:GETDATE() select GETDATE() 返回: 2015-04-27 20:52:06.700 2.返回时间的部分 ...

  6. 常用的开源镜像网站收集与备忘

    常用的开源镜像网站收集与备忘 开源软件,英文表示是open source software,简称为OSS,直接的字面意思是公开源代码的软件,开源软件具备可以免费使用和公布源代码的主要特征,是赋予任何人 ...

  7. linux常用基本指令汇总备忘

    linux常用基本指令汇总备忘 vi编辑界面中可以使用三种不同的工作模式. 分别是命令模式(Command mode):控制光标移动,字符,字或者行的删除,进入其他两个模式 输入模式(Insert m ...

  8. 常用java工具代码备忘

    记录一些常用java工具代码,个人用,备忘 package com.szq.misc;import java.util.UUID;public enum MiscUtils {I;/*** 格式化UR ...

  9. Photoshop2023常用快捷键和使用技巧(作为备忘)

    自己使用PS多年积累下来的史上最全快捷键及个人总结的使用技巧(支持最新版PS2023),作为备忘,如果能顺便帮助到您,望给我个赞!(你如果能把下面东西全部记住并理解,那么你的PS技术层面上的基本功就算 ...

最新文章

  1. boost::spirit模块实现使用单个融合序列来生成不同序列中元素的输出的测试程序
  2. Raid5.h注释翻译
  3. 读书笔记2013-1--暗时间(刘未鹏)
  4. Lintcode--6(767)--翻转数组
  5. Robotium_断言方法assert、is、search
  6. MATLAB路径的正确书写方式
  7. html+css+js实现登录页面
  8. JAVA基础--IO输入输出(File使用)17
  9. linq where的应用
  10. 物流前沿理论与方法1
  11. oracle 索引快速全扫描,使用索引快速全扫描(Index FFS)避免全表扫描的若干场景
  12. Apache部署超详细教程
  13. 鸿蒙蕴含的哲理,蕴含哲理的唯美句子,喜欢的就收藏吧!
  14. 微信认识到成熟应用不该“跳来跳去”
  15. Postman测试http请求返回415状态码的解决
  16. ImageWarping变形算法研究---反距离加权插值(IDW)
  17. 云游 Google I/O 2021——Google Cloud 硬件算力和模型新突破
  18. matlab安装及使用
  19. 写电子邮件是一件严肃的事情
  20. Linux命令date 日期时间和Unix时间戳互转

热门文章

  1. 音频电解电容应用方法及经验
  2. 关于Ultraiso一直显示“设备忙”的解决办法
  3. linux下 kafka的安装
  4. win7 系统装SQLServer2000 成功。
  5. 请问在 1 到 2020 中,有多少个数既是 4 的整数倍,又是 6 的整数倍。
  6. vue 修改地址栏参数
  7. word论文页眉的横线怎么删除去掉
  8. 怎么查询上网帐号和上网口令_宽带上网账号和密码忘记了该怎么查询
  9. win10 计算机管理器没有ime,win10电脑任务栏输入法初选ime禁用的解决方法
  10. 详解视频封装格式之MP4