分享一个自用的表格式流程编辑软件源码
By
admin
at 2021-11-19 • 1人收藏 • 1852人看过


有时候客户需要灵活修改部分功能, 于是就需要你每次提需求改代码改功能, 太麻烦了有木有?
有了这款软件只需要你在你的主程序里解析编写好的流程文件, 然后按照一定的逻辑执行.
这个是我项目里一直再使用的, 给客户在你既定的功能上编写玩的, 然后你的主程序对编好的程序文件进行解析就可以了.
为了能灵活配置自动功能项 , 我把自动完成和自动提示功能用fsys.table来实现, 这样即使客户需要你增加其他功能的流程编辑功能, 只需要修改 流程数据/program.table 这个文件内容即可.
好了, 不藏私, 分享给大家 , 代码难免有一些不简洁的地方, 希望大家能留言共同改进!
表格控件使用了flexcell 6.3.4版本, 库代码在其他帖里找, 表格控件自己去百度.
使用方法:
先在左侧新增流程
右侧鼠标点击右键 , 看到好多菜单, 新增10行
双击[功能名称]那列, 会出现下拉菜单, 选择后, 在双击它后面的那列,继续选择, 后面那些参数会自动填充,
单击你编好的任意一行, 标题栏会自动改变每列的标题为此列的提示信息.
没啥可说了, 看代码吧
有用得到的人吱一声, 当然能留言继续改进更多功能就更赞了.
对了, 附上program.table文件
import process.mutex;
var mutex = process.mutex("6908C972-AB73-4CDE-9DD7-9B5360C7E544")
if( mutex.conflict ){
import win.ui.atom;
var atom,hwndConflict = win.ui.atom.find("E9CB8A6C-4F72-4B2F-8352-DFB3D083FF04")
if( hwndConflict )
{
win.setForeground(hwndConflict);
return;
}
}
import win.ui;
/*DSG{{*/
mainForm = win.form(text="流程编辑";right=1323;bottom=613;border="thin")
mainForm.add(
leftList={cls="static";left=7;top=9;right=240;bottom=568;bgcolor=12639424;db=1;dl=1;dt=1;z=1};
rightList={cls="static";left=245;top=9;right=1321;bottom=568;bgcolor=12632256;db=1;dr=1;dt=1;z=2};
splitter={cls="splitter";left=242;top=9;right=247;bottom=568;db=1;dt=1;frame=1;z=7};
保存={cls="button";text="保 存";left=1011;top=575;right=1159;bottom=610;db=1;dr=1;font=LOGFONT(h=-20);z=3};
取消={cls="button";text="取 消";left=1170;top=575;right=1318;bottom=610;db=1;dr=1;font=LOGFONT(h=-20);z=4};
新增={cls="button";text="新 增";left=245;top=575;right=334;bottom=610;db=1;dl=1;font=LOGFONT(h=-20);z=6};
新增名称={cls="edit";left=6;top=575;right=238;bottom=610;border=1;db=1;dl=1;font=LOGFONT(h=-20);z=5}
)
/*}}*/
import win.ui.atom;
mainForm.atom("E9CB8A6C-4F72-4B2F-8352-DFB3D083FF04");
mainForm.splitter.split(mainForm.leftList,mainForm.rightList);
import fsys.table;
import FlexCellLib;
import win.ui.menu;
import string.database;
//定义左右两侧窗口
var flcLeft,flcRight;
//定义重命名前文件名
var preText;
//定义左侧右键删除项
var deleteRow;
//判断是否有需要保存的数据
var saveFlag = false;
flcLeft = FlexCellLib(mainForm.leftList,1,2);
flcRight = FlexCellLib(mainForm.rightList,1,11);
var 方程集 = fsys.table("\流程数据\progrem.table");
/*点击改变文本颜色{{*/
var rowTextColorChange = function(rowIndex){
if(flcLeft.Rows>1){
for(i=1;flcLeft.Rows-1;1){
if(rowIndex == i){
flcLeft.Cell(rowIndex,1).ForeColor = 0x0000FF;
flcLeft.Cell(rowIndex,1).Font.setBold(true);
}else {
flcLeft.Cell(i,1).ForeColor = 0x000000;
flcLeft.Cell(i,1).Font.setBold(false);
}
}
}
}
/*}}*/
/*CVS文件解析{{*/
var csvPara = function(fileName){
//还原字符串
var toStr = function(str){
return string.fromto(str,936,65001)
}
var txt = string.load("\流程数据\"+fileName+".csv");
var strDb = string.database(",");
var data = strDb.parse(txt); //解析数据
flcRight.AutoRedraw = false;
if(flcRight.Rows>1){
flcRight.Range(1,0,flcRight.Rows-1,0).DeleteByRow();
}
for(i=1;#data;1){
if(i>(flcRight.Rows-1)){
flcRight.AddItem("",false);
}
for(j=1;#data[i];1){
flcRight.Cell(i,j).Text = toStr(data[i][j]);
}
if( data[i][1]=="" or data[i][1]==null ) flcRight.Range(i,1,i,flcRight.Cols-1).BackColor = 0x8273FF;
}
flcRight.AutoRedraw = true;
flcRight.Refresh();
}
/*}}*/
/*右键菜单{{*/
mainForm.Leftpopmenu = win.ui.popmenu(mainForm);//创建弹出菜单
mainForm.Leftpopmenu.add('移除此流程',function(id){
if( deleteRow ){
var Text = flcLeft.Cell(deleteRow,1).Text;
var ret = fsys.delete("\流程数据\"++ Text ++ ".csv");
if(ret){
flcLeft.RemoveItem(deleteRow)
if(deleteRow < (flcLeft.Rows-1)){
rowTextColorChange(deleteRow);
csvPara(flcLeft.Cell(deleteRow,1).Text);
}else {
rowTextColorChange(flcLeft.Rows-1);
csvPara(flcLeft.Cell(flcLeft.Rows-1,1).Text);
}
mainForm.msgbox("删除 "++ Text ++" 流程成功!")
}else {
mainForm.msgboxErr("删除失败!")
}
deleteRow = null;
}
});
flcLeft.MouseUp = function(Button , Shift, x, y){
if(Button == 2){
if( flcLeft.HitTest(x,y) ){
if(saveFlag){
var ret = mainForm.msgboxTest("发现有未保存的数据,是否需要返回并手动保存?");
if(ret){
return;
}
saveFlag = false;
}
deleteRow = flcLeft.HitTest(x,y).Row;
mainForm.Leftpopmenu.popup();
}
}
}
//--------------------------------------------------------
mainForm.Rightpopmenu = win.ui.popmenu(mainForm);//创建弹出菜单
mainForm.Rightpopmenu.add('新增一行',function(id){
//在下面输入菜单响应代码
if(flcLeft.ActiveCell().Text !=""){
flcRight.AddItem("",true);
flcRight.Range(flcRight.Rows-1,1,flcRight.Rows-1,flcRight.Cols-1).BackColor = 0x8273FF;
}else {
mainForm.msgboxErr('请先从左边中选择一个需要编辑的流程\n或者在左侧创建新的流程!');
}
});
mainForm.Rightpopmenu.add('新增十行',function(id){
//在下面输入菜单响应代码
if(flcLeft.ActiveCell().Text !=""){
for(i=1;10;1){
flcRight.AddItem("",true);
flcRight.Range(flcRight.Rows-1,1,flcRight.Rows-1,flcRight.Cols-1).BackColor = 0x8273FF;
}
}else {
mainForm.msgboxErr('请先从左边中选择一个需要编辑的流程\n或者在左侧创建新的流程!');
}
});
mainForm.Rightpopmenu.add('插入行',function(id){
//在下面输入菜单响应代码
if(flcRight.ActiveCell().Text != ""){
flcRight.Selection.InsertRows();
flcRight.Selection.BackColor = 0x8273FF;
}else {
if(flcLeft.ActiveCell().Text !=""){
flcRight.AddItem("",true);
flcRight.Range(flcRight.ActiveCell().Row-1,1,flcRight.ActiveCell().Row-1,flcRight.Cols-1).BackColor = 0x8273FF;
}else {
mainForm.msgboxErr('请先从左边中选择一个需要编辑的流程\n或者在左侧创建新的流程!');
}
}
});
mainForm.Rightpopmenu.add('剪切',function(id){
//在下面输入菜单响应代码
flcRight.Selection.CutData();
});
mainForm.Rightpopmenu.add('复制',function(id){
//在下面输入菜单响应代码
flcRight.Selection.CopyData();
});
mainForm.Rightpopmenu.add('粘贴',function(id){
//在下面输入菜单响应代码
flcRight.Selection.PasteData();
});
mainForm.Rightpopmenu.add('移除选中行',function(id){
//在下面输入菜单响应代码
flcRight.Selection.DeleteByRow();
});
mainForm.Rightpopmenu.add('清除选中行内容',function(id){
//在下面输入菜单响应代码
flcRight.Selection.ClearText();
});
flcRight.MouseUp = function(Button , Shift, x, y){
if(Button == 2){
mainForm.Rightpopmenu.popup();
}
}
/*}}*/
/*初始化界面{{*/
var setListStyle = function(flcobj){
flcobj.BackColorScrollBar = 0xD3AF1C;
flcobj.BackColorActiveCellSel = 0x8273FF;
flcobj.BackColorFixedSel = 0xCCC899;
flcobj.BackColorSel = 0x8273FF;
flcobj.SelectionMode = 1/*_cellSelectionByRow*/;
flcobj.DefaultFont.setSize(15)
}
var setColStyle = function(flcobj,Col,Width,Align=0xA,Text){
if(Width != null){
flcobj.Column(Col).Width = Width;
}
flcobj.Column(Col).Alignment = Align;
flcobj.Cell(0,Col).Text = Text;
}
//----------------
setListStyle(flcLeft);
setColStyle(flcLeft,0,0);
setColStyle(flcLeft,1,,6,"流程名称");
//---------------
setListStyle(flcRight);
setColStyle(flcRight,1,40,,"");
setColStyle(flcRight,2,400,6/*_cellLeftCenter*/,"备 注");
setColStyle(flcRight,3,150,,"功能名称");
setColStyle(flcRight,4,250,,"方法名称");
setColStyle(flcRight,5,150,,"参数一");
setColStyle(flcRight,6,130,,"参数二");
setColStyle(flcRight,7,130,,"参数三");
setColStyle(flcRight,8,130,,"参数四");
setColStyle(flcRight,9,130,,"参数五");
setColStyle(flcRight,10,130,,"参数六");
flcRight.ComboBox(0).Font.setSize(14);
flcRight.Column(1).CellType = 2/*_cellCheckBox*/;
flcRight.Column(3).CellType = 1/*_cellComboBox*/;
flcRight.Column(4).CellType = 1/*_cellComboBox*/;
flcRight.ComboBox(3).Font.setSize(14);
flcRight.ComboBox(4).Font.setSize(14);
/*}}*/
/*枚举所有流程文件{{*/
try{
fsys.enum( "/流程数据", "*.csv",
function(dirpath,dirname){
flcLeft.AddItem(string.replace(dirname,".csv",""),true);
}
);
}
/*}}*/
/*填充默认数据{{*/
if(flcLeft.Rows>1){
//默认选中第一个流程
flcLeft.Range(1,0,1,0).Selected();
rowTextColorChange(1);
csvPara(flcLeft.Cell(1,1).Text);
}
/*}}*/
/*重命名流程功能{{*/
flcLeft.DblClick = function(){
var cellDD = flcLeft.HitTest(flcLeft.MouseRow,flcLeft.MouseCol);
if( cellDD ){
preText = flcLeft.Cell(flcLeft.MouseRow,flcLeft.MouseCol).Text;
}
}
flcLeft.CellChange = function(Row,Col){
if(flcLeft.Cell(Row,Col).Text != ""){
var ret = fsys.rename("\流程数据\"++ preText ++ ".csv","\流程数据\"++ flcLeft.Cell(Row,Col).Text ++ ".csv");
}else {
flcLeft.Cell(Row,Col).Text = preText;
}
}
/*}}*/
/*左侧单击功能{{*/
flcLeft.Click = function(){
if(flcLeft.HitTest(flcLeft.MouseRow,flcLeft.MouseCol)){
rowTextColorChange(flcLeft.MouseRow);
csvPara(flcLeft.Cell(flcLeft.MouseRow,1).Text);
}
}
/*}}*/
/*拦截左侧列表项改变{{*/
flcLeft.LeaveCell = function(Row,Col,newRow,newCol,Cancel){
if(saveFlag){
var ret = mainForm.msgboxTest("发现有未保存的数据,是否需要返回并手动保存?")
if(ret){
return newRow,newCol,true;//;
}
saveFlag = false;
//改变颜色和选项
rowTextColorChange(newRow);
csvPara(flcLeft.Cell(newRow,1).Text);
}
}
/*}}*/
/*保存功能{{*/
mainForm.保存.oncommand = function(id,event){
var fileName = flcLeft.ActiveCell().Text;
if(fileName != null and fileName != ""){
saveFlag = false;
flcRight.ExportToCSV(fsys.getCurDir()++"\流程数据\"++ fileName ++ ".csv");
}
}
/*}}*/
/*新增流程{{*/
mainForm.新增.oncommand = function(id,event){
if(saveFlag){
var ret = mainForm.msgboxTest("发现有未保存的数据,是否需要返回并手动保存?");
if(ret){
return;
}
saveFlag = false;
}
if(mainForm.新增名称.text != null and mainForm.新增名称.text != ""){
var ret = io.exist( "\流程数据\"++ mainForm.新增名称.text ++ ".csv" );
if(ret == null){
var ret = string.save("\流程数据\"++ mainForm.新增名称.text ++ ".csv","");
if(ret){
flcLeft.AddItem(mainForm.新增名称.text,true)
flcLeft.Range(flcLeft.Rows-1,0,flcLeft.Rows-1,0).Selected();
rowTextColorChange(flcLeft.Rows-1);
flcLeft.Cell(flcLeft.Rows-1,1).EnsureVisible();
csvPara(mainForm.新增名称.text);
mainForm.msgbox("创建 "++ mainForm.新增名称.text ++" 流程成功!" )
}
}else {
mainForm.msgbox( "流程已存在!" );
}
}
}
/*}}*/
/*方程集的数据表处理{{*/
var 获取参数类型和值 = function(tab,...){
var namesTab = {...};
if(#namesTab!=0){
var tempTab = tab;
for(i=1;#namesTab;1){
tempTab = tempTab[namesTab[i]]
}
select(tempTab.类型) {
case "下拉框" {
return 1/*_cellComboBox*/,tempTab.值;
}
case "文本框" {
return 0/*_cellTextBox*/,tempTab.值;
}
case "复选框" {
return 2/*_cellCheckBox*/,tempTab.值;
}
else {
return null;
}
}
}
return null;
}
var 获取参数提示 = function(tab,...){
var namesTab = {...};
if(namesTab[1]=="" and namesTab[2]=="" and namesTab[3]=="" and namesTab[4]=="" and namesTab[5]=="" and namesTab[6]==""){
return {"参数一","参数二","参数三","参数四","参数五","参数六";}
}
if(#namesTab!=0){
var tempTab = tab;
for(i=1;#namesTab;1){
tempTab = tempTab[namesTab[i]]
}
return {(tempTab.参数一.提示=="")?"参数一":tempTab.参数一.提示,(tempTab.参数二.提示=="")?"参数二":tempTab.参数二.提示,(tempTab.参数三.提示=="")?"参数三":tempTab.参数三.提示,(tempTab.参数四.提示=="")?"参数四":tempTab.参数四.提示,(tempTab.参数五.提示=="")?"参数五":tempTab.参数五.提示,(tempTab.参数六.提示=="")?"参数六":tempTab.参数六.提示,tempTab.参数一.类型,tempTab.参数二.类型,tempTab.参数三.类型,tempTab.参数四.类型,tempTab.参数五.类型,tempTab.参数六.类型};
}
return {"参数一","参数二","参数三","参数四","参数五","参数六","文本框","文本框","文本框","文本框","文本框","文本框"};
}
var 获取表名 = function(tab,...){
var namesTab = {...};
var keyNameTab={};
if(#namesTab!=0){
var tempTab = tab;
for(i=1;#namesTab;1){
tempTab = tempTab[namesTab[i]]
}
for(k,v in tempTab){
table.push(keyNameTab,k);
}
}else {
for(k,v in tab){
table.push(keyNameTab,k);
}
}
return keyNameTab;
}
/*}}*/
/*右侧流程界面智能提示功能{{*/
flcRight.ComboDropDown = function(Row,Col){
if(Col == 3){
flcRight.ComboBox(3).Clear();
var names = 获取表名(方程集);
for(i=1;#names;1){
flcRight.ComboBox(3).AddItem(names[i]);
}
}
if(Col == 4){
flcRight.ComboBox(4).Clear();
var names = 获取表名(方程集,flcRight.Cell(Row,3).Text);
for(i=1;#names;1){
flcRight.ComboBox(4).AddItem(names[i]);
}
}
var 设置下拉参数和值 = function(name){
var ret1,ret2 = 获取参数类型和值(方程集,flcRight.Cell(Row,3).Text,flcRight.Cell(Row,4).Text,name)
for(i=1;#ret2;1){
flcRight.ComboBox(0).AddItem(ret2[i]);
}
}
if(Col == 5){
设置下拉参数和值("参数一");
}
if(Col == 6){
设置下拉参数和值("参数二");
}
if(Col == 7){
设置下拉参数和值("参数三");
}
if(Col == 8){
设置下拉参数和值("参数四");
}
if(Col == 9){
设置下拉参数和值("参数五");
}
if(Col == 10){
设置下拉参数和值("参数六");
}
}
flcRight.DblClick = function(){
//防止双击到空白处
if(flcRight.MouseRow != -1){
saveFlag = true;
}
if(flcRight.Cell(flcRight.MouseRow,flcRight.MouseCol).CellType == 6/*_cellDefault*/){
win.delay(200)
flcRight.ComboBox(flcRight.MouseCol).DropDown()
}elseif(flcRight.Cell(flcRight.MouseRow,flcRight.MouseCol).CellType == 1/*_cellComboBox*/){
win.delay(200)
flcRight.ComboBox(0).DropDown()
}
}
flcRight.CellChange = function(Row,Col){
if(Col==1){
if(Row!=0){
if( !flcRight.Cell(Row,1).BooleanValue ) flcRight.Range(Row,1,Row,flcRight.Cols-1).BackColor = 0x8273FF;
else flcRight.Range(Row,1,Row,flcRight.Cols-1).BackColor = (Row%2==0)?flcRight.BackColor2:flcRight.BackColor1;
}
};
if(Col==3){
flcRight.Range(Row,4,Row,flcRight.Cols-1).ClearText()
for(i=4;flcRight.Cols-1;1){
flcRight.Cell(Row,i).text = "";
}
}
if(Col==4){
flcRight.Range(Row,5,Row,flcRight.Cols-1).ClearText();
if(flcRight.Cell(Row,3).Text!=""){
var retTable = 获取参数提示(方程集,flcRight.Cell(Row,3).Text,flcRight.Cell(Row,4).Text);
for(i=5;flcRight.Cols-1;1){
flcRight.Cell(0,i).Text = retTable[i-4];
}
///--------------------------------------------------------------
var 设置参数类型和值 = function(selcol,name){
var ret1,ret2 = 获取参数类型和值(方程集,flcRight.Cell(Row,3).Text,flcRight.Cell(Row,4).Text,name)
if(ret1 != null){
flcRight.Cell(Row,selcol).CellType = ret1;
if(type(ret2) == type.table){
flcRight.Cell(Row,selcol).text = ret2[1];
}else {
flcRight.Cell(Row,selcol).text = ret2;
}
}else {
flcRight.Cell(Row,selcol).text = "------";
flcRight.Cell(Row,selcol).CellType = 0/*_cellTextBox*/;
}
}
设置参数类型和值(5,"参数一");
设置参数类型和值(6,"参数二");
设置参数类型和值(7,"参数三");
设置参数类型和值(8,"参数四");
设置参数类型和值(9,"参数五");
设置参数类型和值(10,"参数六");
}
}
}
/*}}*/
/*流程界面行点击改变表头提示功能{{*/
flcRight.Click = function(){
if( flcRight.HitTest(flcRight.MouseRow,flcRight.MouseCol) ){
var retTable = 获取参数提示(方程集,flcRight.Cell(flcRight.MouseRow,3).Text,flcRight.Cell(flcRight.MouseRow,4).Text);
for(i=5;flcRight.Cols-1;1){
flcRight.Cell(0,i).Text = retTable[i-4];
}
var styleTab={};
for(i=5;flcRight.Cols-1;1){
table.push(styleTab,retTable[i-4+6]);
}
//-------------------
for(i=1;6;1){
select(styleTab[i]) {
case "下拉框" {
flcRight.Cell(flcRight.MouseRow,i+4).CellType = 1;
}
}
}
}
}
/*}}*/
mainForm.取消.oncommand = function(id,event){
saveFlag = false;
if(flcLeft.ActiveCell().Text){
csvPara(flcLeft.ActiveCell().Text);
}
}
mainForm.onClose = function(hwnd,message,wParam,lParam){
if(saveFlag){
var ret = mainForm.msgboxTest("发现有未保存的数据,是否需要返回并手动保存?");
if(ret){
//阻止关闭窗口
return true;
}
saveFlag = false;
//继续关闭
}
}
mainForm.show();
return win.loopMessage();
4 个回复 | 最后更新于 2021-11-22
登录后方可回帖

会不会是不知道怎么使用? 感觉没人感兴趣
生成流程后使用方法:
通过string.database解析流程文件(例如 demo.csv)为table表,
然后写一个解析每行数据的函数就可以了.
var doLine = function(lineTab){ select(lineTab[3]) {//我上面是从第三列开始是首程序函数名,后面是参数1,参数2... case "硬件控制" { select(lineTab[4]) { case "脉冲发生器" { select(lineTab[5]) { case "启动" { 启动(...); } case "停止" { 停止(...); } case "单次运行" { 单次运行(...); } else { } } } case "IO控制" { select(lineTab[5]) { case "demo1" { 你的函数(demo1); } case "demo2" { 你的函数(demo2); } else { } } } else { } } } case "运动控制" { select(lineTab[4]) { case "相对运动" { var 轴号 = 返回轴号(lineTab[5]); var 速度 = tonumber(lineTab[6]); var 距离 = tonumber(lineTab[7]); 你的运动函数(轴号,速度,距离); } case ... { 你的函数(...) } else { } } } case "方法调用" { ... } else { } } }