Genero学习作品之点餐系统

  这个。。。自学的开发语言如果不去做几个项目真的等于白学啊!前段时间看的语法忘记得差不多了哭,赶紧来个列子温故下。


点餐系统:1.Excel上传本地菜单到数据库




点餐系统:2.点餐系统界面FORM



点餐系统:3.运行点餐系统

Genero学习作品之点餐系统_第1张图片

点击按钮BOOKING 开始点餐,屏幕输入信息及选择下拉框,输入完成以后点击OK

Genero学习作品之点餐系统_第2张图片


再点击Append按钮,加入购物清单,如需继续点购别的食品,再次点击BOOKING,只输入食品及数量即可,Append到购物清单

Genero学习作品之点餐系统_第3张图片


如果不喜欢吃蔬菜,可以点击Delete按钮,输入Line: 4即可删除购物清单中的蔬菜

Genero学习作品之点餐系统_第4张图片


最后点击Commit按钮,提交本次点餐清单,提示本次购物总金额,确认是否提交,点击OK,数据写入数据库

Genero学习作品之点餐系统_第5张图片



源码部分:1.上传菜单,本人注释很清楚,不解释

GLOBALS
 CONSTANT l_connect STRING = "AnyDBName+driver='dbmmys55x',source = 'mytest@localhost:3306'"
END GLOBALS


MAIN
  DEFINE path STRING #定义文件路径


  PROMPT "Enter file path: " FOR path  #弹出对话框,输入文件地址


  CALL excel_upload(path) #上传指定路劲的EXCEL数据到数组
END MAIN


FUNCTION excel_upload(p_path)
  DEFINE p_path STRING
  DEFINE i,j,r_app,r_wb,r_row INT


  DEFINE datain DYNAMIC ARRAY OF RECORD  #定义动态数组保存EXCEL数据
    col1 CHAR(10),
    col2 CHAR(20)
#    col3 CHAR(30)
  END RECORD
  
  CALL ui.interface.frontCall('WinCOM','CreateInstance',['Excel.Application'],[r_app])  #创建excel实例 
  CALL CheckError(r_app, __LINE__)
  CALL ui.interface.frontCall('WinCOM','CallMethod',[r_app,'WorkBooks.Open',p_path],[r_wb]) #打开workbook
  CALL CheckError(r_wb, __LINE__)
  CALL ui.interface.frontCall('WinCOM','GetProperty',[r_app,'ActiveSheet.UsedRange.Rows.Count'],[r_row])  #得到excel数据条目
  CALL CheckError(r_row, __LINE__)


  IF r_row > 1 THEN   #第一行栏位名不要,第二行开始
    FOR i = 2 TO r_row
      CALL ui.interface.frontCall('WinCOM','GetProperty',[r_app,'ActiveSheet.Cells('||i||',1).Value'],[datain[i-1].col1]) #从sheet写第一列数据到数组
      CALL ui.interface.frontCall('WinCOM','GetProperty',[r_app,'ActiveSheet.Cells('||i||',2).Value'],[datain[i-1].col2]) #从sheet写第二列数据到数组
#      CALL ui.interface.frontCall('WinCOM','GetProperty',[r_app,'ActiveSheet.Cells('||i||',3).Value'],[datain[i-1].col3]) #从sheet写第三列数据到数组
    END FOR
  END IF


  #记得关闭打开的实例,释放内存
  CALL ui.interface.frontCall('WinCOM','CallMethod',[r_app,'Quit'],[r_wb])  
  CALL ui.interface.frontCall('WinCOM','ReleaseInstance',[r_app],[r_wb])  


  CONNECT TO l_connect USER "root" USING "123456"
IF SQLCA.SQLCODE THEN
 EXIT PROGRAM SQLCA.SQLCODE
END IF
  WHENEVER ERROR CONTINUE  #数据库处理过程避免错误导致直接退出,执行失败消息
  PREPARE p1 FROM "INSERT INTO food VALUES (?,?)"  #存储到数据库
  LET j = 1
  FOR j = 1 TO (r_row - 1)    #显示一下
    DISPLAY datain[j].* 
    EXECUTE p1 USING datain[j].*     #执行SQL,INSERT结果
    IF SQLCA.sqlcode <> 0 THEN
      DISPLAY "upload food fail!"
      RETURN
    END IF
  END FOR
  DISPLAY "upload success!"
  FREE p1
END FUNCTION


FUNCTION checkerror(result, lin)  #抓取错误信息
  DEFINE result,lin INT
  DEFINE mess STRING


  IF result = -1 THEN
    DISPLAY "COM ERROR AT LINE: ", lin
    CALL ui.interface.frontCall('WinCOM',"GetError",[],[mess])
    DISPLAY mess
    EXIT PROGRAM -1
  END IF
END FUNCTION


源码部分:2.点餐系统设计,注释依然很清楚,别让我说什么

#定义用于屏幕输入的下拉食品清单
DEFINE foodlist DYNAMIC ARRAY OF RECORD
 food CHAR(20),
 price INT
END RECORD


#定义屏幕输入组
DEFINE s_input RECORD
 g_date DATE,
 g_po,g_name,g_phone,g_lunch CHAR(20),
 g_count, g_price, g_price_t INT
END RECORD


#定义用于显示的Item
DEFINE s_table DYNAMIC ARRAY OF RECORD
 LINE INT,
 date DATE,
 po CHAR(20),
 name CHAR(20),
 phone CHAR(20),
 lunch CHAR(20),
 COUNT INT,
 price INT
END RECORD


DEFINE i, x INT
DEFINE cb1, cb2 ui.ComboBox  
DEFINE l_price,l_price_t, l_count, l_price_a INT
DEFINE l_po CHAR(20),
       c_price CHAR(5)


MAIN
DEFINE l_connect STRING
DEFINE s1 STRING


#链接数据库
LET l_connect = "AnyDBName+driver='dbmmys55x',source = 'mytest@localhost:3306'"
CONNECT TO l_connect USER "root" USING "123456"
IF SQLCA.SQLCODE THEN
 EXIT PROGRAM SQLCA.SQLCODE
END IF


#打开FORM
  OPEN FORM f1 FROM "lunch_screen"
  DISPLAY FORM f1


#抓取食品清单
  DECLARE c1 CURSOR FOR SELECT food,price FROM food


#初始化全局变量
  LET  i = 1
  LET  x = 1  


#MENU定义 用户Action操作  
MENU 'On-line Meal System-Operation'
  BEFORE MENU
    CALL food_list()  #显示MENU之前,准备好输入界面lunch的下拉框食品清单
  ON ACTION BOOKING   #点击订餐按钮
     IF x = 1 THEN
       CALL screen_input_fist()   #第一次进入输入所有栏位
       LET x = x + 1
     ELSE
       CALL screen_input_next()   #之后只需要输入点购的食品及数量   
     END IF
  ON ACTION APPEND   #点击加入按钮 
     CALL append_table() #将屏幕输入信息加入Table Item
  ON ACTION DELETE  #点击删除按钮
     CALL delete_table() #删除指定行的订餐数据
  ON ACTION COMMIT   #提交点餐数据
  #提示订单总价,确认是否提交订单
     LET c_price = l_price_a
     LET s1 = "Total price: ",c_price, " You sure commit ?"  
     IF fgl_winQuestion("Commit",
         s1,"yes", "no|yes", "help", 0) == "yes" THEN
       CALL insert_table()   #写入数据库
     END IF 
  ON ACTION CANCEL
     EXIT PROGRAM     #退出表单
END MENU    
 
  CLOSE c1
  CLOSE FORM f1
END MAIN




FUNCTION screen_input_fist()
DEFINE l_year CHAR(4), 
       l_month, l_day CHAR(2)


  LET l_count = 0
  LET l_price = 0
  LET l_price_t = 0


#第一次进入点餐输入全部栏位
  INPUT BY NAME s_input.g_date, s_input.g_count, s_input.g_lunch, s_input.g_name, s_input.g_phone
   AFTER INPUT 
    LET l_po = l_year,l_month,l_day,s_input.g_phone  #全部输入完成以后根据日期及电话号码生成PO
    DISPLAY l_po TO g_po
  ON CHANGE g_lunch, g_count    #改变食品或者订餐数量价格栏位自动计算并显示
    CALL get_food_price() RETURNING l_price   #根据用户选择的食品名抓取价格
    CALL count_list() RETURNING l_count   #得到用户选择的食品数量
    LET l_price_t = l_price * l_count  #得到该食品单品的总价格
    DISPLAY l_price TO g_price   #显示单价
    DISPLAY l_price_t TO g_price_t  #显示该食品总价
   ON CHANGE g_phone, g_date   #输入日期,联系方式
   #重组日期格式用于PO
    LET l_year = Year(s_input.g_date)
    LET l_month = Month(s_input.g_date)
    LET l_day = DAY(s_input.g_date)
   ON ACTION CANCEL
    EXIT INPUT   #退出输入
  END INPUT


  LET s_input.g_price = l_price
  LET s_input.g_price_t = l_price_t
  LET s_input.g_po = l_po 
  LET s_input.g_lunch = cb1.getItemText(s_input.g_lunch)   
END FUNCTION



FUNCTION screen_input_next()
  CLEAR g_price, g_price_t   #清除价格数据,重新计算
  
  LET l_count = 0
  LET l_price = 0
  LET l_price_t = 0
  
  INPUT BY NAME s_input.g_count, s_input.g_lunch  #只需要输入点购的食品和数量
  #得到食品的价格和数量,重新计算价格信息
   ON CHANGE g_lunch, g_count   
    CALL get_food_price() RETURNING l_price
    CALL count_list() RETURNING l_count
    LET l_price_t = l_price * l_count
    DISPLAY l_price TO g_price
    DISPLAY l_price_t TO g_price_t
   ON ACTION CANCEL
    EXIT INPUT   
  END INPUT  


  LET s_input.g_price = l_price
  LET s_input.g_price_t = l_price_t
  LET s_input.g_lunch = cb1.getItemText(s_input.g_lunch)    
END FUNCTION




FUNCTION food_list()
 LET cb1 = ui.ComboBox.forName("g_lunch")  #得到ComboBox对象
 IF cb1 IS NULL THEN
   ERROR "Form field not found in current form"
   EXIT PROGRAM
 END IF
 CALL cb1.clear()      #清除ComboBox里的数据
 CALL foodlist.CLEAR()  #清除食品清单
 
 FOREACH c1 INTO foodlist[i].*   #将食品清单添加到ComboBox中去
   CALL cb1.addItem(i, foodlist[i].food)
   LET i = i + 1
 END FOREACH


 IF i = 1 THEN     
   ERROR "No food find !"
 END IF 
 
 LET i = i - 1     #得到最终食品清单的数量
END FUNCTION



FUNCTION get_food_price( )
  DEFINE ch2 CHAR(20),
         z INT,
         re1 INT
  LET ch2 = cb1.getItemText(s_input.g_lunch)   #得到ComboBox用户选择的Item食品名称
 
  FOR z = 1 TO i
    IF foodlist[z].food MATCHES ch2 THEN   #根据食品名去匹配食品清单主数据,得到食品价格
       LET re1 = foodlist[z].price
     EXIT FOR
    END IF
  END FOR
  RETURN re1     #返回食品价格
END FUNCTION



FUNCTION count_list()
DEFINE re2 INT
LET cb2 = ui.ComboBox.forName("g_count")   #得到ComboBox对象
IF cb2 IS NULL THEN
  ERROR "Form field not found in current form"
  EXIT PROGRAM
END IF
  LET re2 = cb2.getItemText(s_input.g_count)  #得到ComboBox用户选择的食品数量
  RETURN re2    #返回食品数量
END FUNCTION


FUNCTION append_table()
 DEFINE y INT
 #如果食品有价格则将屏幕数据放入Table中去,并显示
 IF s_input.g_price_t > 0 THEN
  LET y = s_table.getLength()
  LET y = y + 1
  
  LET s_table[y].date = s_input.g_date
  LET s_table[y].po = s_input.g_po
  LET s_table[y].name = s_input.g_name
  LET s_table[y].lunch = s_input.g_lunch
  LET s_table[y].phone = s_input.g_phone
  LET s_table[y].count = s_input.g_count
  LET s_table[y].price = s_input.g_price_t
  LET s_table[y].line = y
  DISPLAY s_table[y].* TO list[y].*
  DISPLAY y TO g_index
  #每次Table加入一笔数据累加一次,计算食品的总价格
  LET l_price_a = l_price_a + s_input.g_price_t
 ELSE
  ERROR "Price equal 0" 
 END IF 
END FUNCTION



FUNCTION delete_table()
DEFINE i_line, m, n INT
#弹窗提示用户输入要删除的line
  PROMPT "Delete Line: " FOR i_line ATTRIBUTES(normal)
    ON ACTION CANCEL
      RETURN
   END PROMPT  
  LET m = s_table.getLength()
  IF m < i_line THEN
    ERROR "Line not exsit!"
    RETURN
  END IF 
#食品总价格减去被删除的食品价格  
  LET l_price_a = l_price_a - s_table[i_line].price
  CALL s_table.deleteElement(i_line)  #删除指定行订购数据
  FOR n = i_line TO m   #重新计算line,并显示
   LET s_table[n].LINE = s_table[n].LINE - 1
   CLEAR list[n].*
   DISPLAY s_table[n].* TO list[n].*  
  END FOR
  CALL s_table.deleteElement(m)
  DISPLAY (m-1) TO g_index  #右下角显示总的line数
END FUNCTION


FUNCTION insert_table()
  DEFINE p, q INT
  LET q = s_table.getLength()  
  WHENEVER ERROR CONTINUE     #数据库处理过程避免错误导致直接退出,执行失败消息
  PREPARE p1 FROM "INSERT INTO booking_food VALUES (?,?,?,?,?,?)"   #将Table输入插入数据库中
  FOR P = 1 TO q    
    EXECUTE p1 USING s_table[p].po,s_table[p].name,s_table[p].phone,
                     s_table[p].lunch,s_table[p].count,s_table[p].price 
    IF SQLCA.sqlcode <> 0 THEN   #失败消息
      ERROR "commit fail!"
      RETURN    
    END IF
  END FOR
  MESSAGE "commit sucess!"
  FREE p1  
END FUNCTION


最后,我们依然要多假想。。。。。

你可能感兴趣的:(DB,Excel,connect,Genero)