设计用户窗体
下表是个简单的“入职员工信息”数据库,用户窗体用于收集信息并将数据信息保存到该数据库中。
打开VBE,插入用户窗体,默认名为UserForm1。按下表在用户窗体中添加控件并设置属性。
完成的用户窗体如下图所示。
编写代码
1 编写找到数据库工作表中下一个空白行的代码
在VBE中,插入一个类模块,并命名为cExcelUtils,输入下列代码:
Function FindEmptyRow(ws As Worksheet) As LongDim lngReturn As LonglngReturn = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).RowFindEmptyRow = lngReturnEnd Function
2 编写代码以包含每个员工信息的值,以及存储数据库工作表的位置,将数据保存到数据库
插入一个类模块,并命名为cEmployeeInfo,添加下面的代码在模块的声明部分:
Private m_lngID As LongPrivate m_strNameAs StringPrivate m_strSchool As StringPrivate m_blnAbility As BooleanPrivate m_blnObeyAs BooleanPrivate m_xlWkshtAs WorksheetPrivate m_oXLAs cExcelUtils
前5个变量是我们在用户窗体中要输入的数据,以及从数据库工作表中产生的ID字段。变量m_xlWksht包含数据库工作表的位置。变量m_oXL决定在哪里放置新数据。
首先,添加数据属性。
Property Get ID() As LongID = m_lngIDEnd Property Property Get Name() As StringName = m_strNameEnd Property Property Let Name(newName As String)m_strName = newNameEnd Property Property Get School() As StringSchool = m_strSchoolEnd Property Property Let School(newSchool As String)m_strSchool = newSchoolEnd Property Property Get Ability() As BooleanAbility = m_blnAbilityEnd Property Property Let Ability(newAbility As Boolean)m_blnAbility = newAbilityEnd Property Property Get Obey() As BooleanObey = m_blnObeyEnd Property Property Let Obey(newObey As Boolean)m_blnObey = newObeyEnd Property Property Get DBWorkSheet() As WorksheetSet DBWorkSheet = m_xlWkshtEnd Property Property Set DBWorkSheet(newSheet As Worksheet)Set m_xlWksht = newSheetEnd Property
注意,ID属性没有Property Let方法,因此该属性是只读的。
下面,添加GetNextID方法找到最后一行,从第一列中获取值,然后增加1,以此来设置ID属性的值。
Public Function GetNextID() As LongDim lngReturn As LonglngReturn = m_xlWksht.Cells(Rows.Count, 1).End(xlUp).Value + 1m_lngID = lngReturn '设置ID属性GetNextID = lngReturnEnd Function
接下来,添加初始化和清除代码:
Private Sub Class_Initialize()Set m_oXL = New cExcelUtilsEnd Sub Private Sub Class_Terminate()Set m_oXL = NothingEnd Sub
再继续完善该类的功能。先添加一些验证代码。如果Name属性和School属性没有数据的话,则不会保存记录。
Public Function ValidateData() As BooleanDim blnReturn As BooleanIf (Len(Me.Name &"") * Len(Me.School &"")) = 0 ThenblnReturn = FalseElseblnReturn = TrueEnd IfValidateData = blnReturnEnd Function
通过文本值的长度相乘,能够决定是否填充数据。
接下来,编写保存功能的代码。需要知道下一个可用行的行号为数据输入,需要知道该行所在的工作表,并且如果没有错误,返回True。
Public Function Save() As BooleanDim lngNewRowNum As LongDim blnReturn As Boolean If m_xlWksht Is Nothing ThenblnReturn = FalseGoTo Exit_FunctionEnd If lngNewRowNum = m_oXL.FindEmptyRow(m_xlWksht) With m_xlWksht.Cells(lngNewRowNum, 1).Value = Me.ID.Cells(lngNewRowNum, 2).Value = Me.Name.Cells(lngNewRowNum, 3).Value = Me.School.Cells(lngNewRowNum, 4).Value = Me.Ability.Cells(lngNewRowNum, 5).Value = Me.ObeyEnd With If Err.Number = 0 ThenblnReturn = TrueEnd If Exit_Function:Save = blnReturnExit FunctionEnd Function
代码首先检查以确保工作表对象存在,如果不存在则返回False并退出函数。接下来,从cExcelUtils对象中获取空行位置。然后,使用代表数据库工作表的m_xlWksht变量,使用从类属性中的数据填充每列。最后,检查没有发生错误,设置返回值为True,然后退出函数。
这就是cEmployeeInfo类,包含从用户窗体中的输入值,为任何新记录找到下一个ID值,保存数据到工作表中下一个空行。
编写用户窗体代码
在用户窗体代码模块中添加下列模块级变量:
Private m_oEmployeeInfo As cEmployeeInfoPrivate m_blnSaved As Boolean
变量m_blnSaved存储从m_oEmployeeInfo对象的Save方法中返回的值。下面,编写用户窗体初始化和中止事件代码:
Private Sub UserForm_Initialize()Set m_oEmployeeInfo = New cEmployeeInfoSet m_oEmployeeInfo.DBWorkSheet = Sheets("入职员工信息")m_oEmployeeInfo.GetNextIDlblID.Caption = m_oEmployeeInfo.IDm_blnSaved = FalseClearFormEnd Sub Private Sub UserForm_Terminate()Set m_oEmployeeInfo = NothingEnd Sub
在用户窗体初始化时,实例化oEmployeeInfo对象,然后设置DBWorksheet属性。然后,获取下一个可用的ID号并将其放置到标签中。也清除了窗体中的控件值。
Private Sub ClearForm()Me.txtName.Value = ""Me.txtSchool.Value = ""Me.chkAbility.Value = FalseMe.chkObey.Value = FalseEnd Sub
用户窗体中有三个命令按钮:一个用于保存输入的数据,一个用于清除用户窗体数据并添加新记录,一个用于取消数据输入 *** 作并且不保存数据而关闭用户窗体。
“保存”按钮应该执行下列功能:
发送数据到cEmployeeInfo类
验收数据,如果数据无效则返回一条消息
如果数据有效则保存数据,并且如果保存成功则返回一条消息
保存后清除用户窗体数据,并重设保存标志
代码如下:
Private Sub cmdSave_Click()With m_oEmployeeInfo.Name = txtName.Text.School = txtSchool.Text.Ability = chkAbility.Value.Obey = chkObey.ValueEnd WithIf Not m_oEmployeeInfo.ValidateData ThenMsgBox "姓名和毕业院校必填", vbOKOnly, "不能保存"Exit SubElsem_blnSaved = m_oEmployeeInfo.SaveEnd IfDoAfterSave m_blnSavedEnd Sub
过程DoAfterSave用于执行清理。
Private Sub DoAfterSave(success As Boolean)If success ThenClearFormlblID.Caption = m_oEmployeeInfo.GetNextIDMsgBox "记录已保存"ElseMsgBox "没有保存记录"End Ifm_blnSaved = False '重设标志End Sub
“新建”按钮的代码如下,在新建之前,检查文本字段看用户窗体中是否有任何数据:
Private Sub cmdNew_Click()'为新记录设置窗体Dim iAnswer As Integer'检查当前记录是否被保存If Not m_blnSaved Then '是否有输入的文本没有被保存If (Len(Me.txtName.Value &"") + Len(Me.txtSchool.Value &"")) <>0 TheniAnswer = MsgBox("有没有保存的数据,想继续吗?", vbYesNo, "没有保存数据")If iAnswer = vbYes ThenClearFormEnd IfElseClearFormEnd IfEnd IfEnd Sub
“取消”按钮用来清除用户窗体并关闭该用户窗体:
Private Sub cmdCancel_Click()ClearFormUnload UserForm1End Sub
现在,运行用户窗体来看看效果。
以下是我的程序,刚编好的,刚好符合你的要求,看看吧,对你应该有帮助:呵呵
#include
#include
#include
#include
#define N 100
struct employee
{
int num
char name[10]
char sex
int age
char xueli[30]
int wage
char addr[30]
long int tel
}em[100]/*定义一个结构体*/
void menu()
void input()
void save(int)
void display()
void del()
void add()
void search()
void search_num()
void search_xueli()
void search_tel()
void modify()/*定义各函数*/
void menu() /*菜单函数*/
{
printf(" ☆☆☆计算机科学与技术学系☆☆☆\n")
printf("\n")
printf(" ∮08802班 关丽霞∮\n")
printf("\n")
printf(" ******************职工信息管理****************\n")
printf(" 1.录入职工信息")
printf(" 2.浏览职工信息\n")
printf(" 3.查询职工信息")
printf(" 4.删除职工信息\n")
printf(" 5.添加职工信息")
printf(" 6.修改职工信息\n")
printf(" 7.退出\n")
printf(" ********************谢谢使用******************\n")
printf("\n")
printf("\n")
}
void main()
{
menu()/*调用菜单函数*/
int n,flag
char a
do
{
printf("请选择你需要 *** 作的步骤(1--7):\n")
scanf("%d",&n)
if(n>=1&&n<=7)
{
flag=1
break
}
else
{
flag=0
printf("您输入有误,请重新选择!")
}
}
while(flag==0)
while(flag==1)
{
switch(n)
{
case 1:printf(" ◆◆◆输入职工信息◆◆◆\n")printf("\n")input()break
case 2:printf(" ◆◆◆浏览职工信息◆◆◆\n")printf("\n")display()break
case 3:printf(" ◆◆◆按职工号查询职工信息◆◆◆\n")printf("\n")search()break
case 4:printf(" ◆◆◆删除职工信息◆◆◆\n")printf("\n")del()break
case 5:printf(" ◆◆◆添加职工信息◆◆◆\n")printf("\n")add()break
case 6:printf(" ◆◆◆修改职工信息◆◆◆\n")printf("\n")modify()break
case 7:exit(0)break
default :break
}
getchar()
printf("\n")
printf("是否继续进行(y or n):\n")
scanf("%c",&a)
if(a=='y')
{
flag=1
system("cls")/*清屏*/
menu()/*调用菜单函数*/
printf("请再次选择你需要 *** 作的步骤(1--6):\n")
scanf("%d",&n)
printf("\n")
}
else
exit(0)
}
}
void input() /*录入函数*/
{
int i,m
printf("请输入需要创建信息的职工人数(1--100):\n")
scanf("%d",&m)
for (i=0i<mi++)
{
printf("职工号: ")
srand((int)time(0))
em[i].num=rand()%10000+20000000
if(em[i].num!=em[i-1].num)
printf("%8d ",em[i].num)
printf("\n")
printf("请输入姓名: ")
scanf("%s",em[i].name)
getchar()
printf("请输入性别(f--女 m--男): ")
scanf("%c",&em[i].sex)
printf("请输入年龄: ")
scanf("%d",&em[i].age)
printf("请输入学历: ")
scanf("%s",em[i].xueli)
printf("请输入工资: ")
scanf("%d",&em[i].wage)
printf("请输入住址: ")
scanf("%s",em[i].addr)
printf("请输入电话: ")
scanf("%d",&em[i].tel)
printf("\n")
}
printf("\n创建完毕!\n")
save(m)
}
void save(int m) /*保存文件函数*/
{
int i
FILE*fp
if ((fp=fopen("employee_list","wb"))==NULL) /*创建文件并判断是否能打开*/
{
printf ("cannot open file\n")
exit(0)
}
for (i=0i<mi++) /*将内存中职工的信息输出到磁盘文件中去*/
if (fwrite(&em[i],sizeof(struct employee),1,fp)!=1)
printf("file write error\n")
fclose(fp)
}
int load() /*导入函数*/
{
FILE*fp
int i=0
if((fp=fopen("employee_list","rb"))==NULL)
{
printf ("cannot open file\n")
exit(0)
}
else
{
do
{
fread(&em[i],sizeof(struct employee),1,fp)
i++
}
while(feof(fp)==0)
}
fclose(fp)
return(i-1)
}
void display() /*浏览函数*/
{
int i
int m=load()
printf("\n 职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n")
for(i=0i<mi++) /*m为输入部分的职工人数*/
printf("\n %d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel)
}
void del() /*删除函数*/
{
int m=load()
int i,j,n,t,flag
char name[20]
printf("\n 原来的职工信息:\n")
display()/* 调用浏览函数*/
printf("\n")
printf("请输入要删除的职工的姓名:\n")
scanf("%s",name)
for(flag=1,i=0flag&&i<mi++)
{
if(strcmp(em[i].name,name)==0)
{
printf("\n已找到此人,原始记录为:\n")
printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n")
printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel)
printf("\n确实要删除此人信息请按1,不删除请按0\n")
scanf("%d",&n)
if(n==1) /*如果删除,则其他的信息都往上移一行*/
{
for(j=ij<m-1j++)
{
strcpy(em[j].name,em[j+1].name)
em[j].num=em[j+1].num
em[j].sex=em[j+1].sex
em[j].age=em[j+1].age
strcpy(em[j].xueli,em[j+1].xueli)
em[j].wage=em[j+1].wage
strcpy(em[j].addr,em[j+1].addr)
em[j].tel=em[j+1].tel
}
flag=0
}
}
}
if(!flag)
m=m-1
else
printf("\n对不起,查无此人!\n")
printf("\n 浏览删除后的所有职工信息:\n")
save(m)/*调用保存函数*/
display()/*调用浏览函数*/
printf("\n继续删除请按1,不再删除请按0\n")
scanf("%d",&t)
switch(t)
{
case 1:del()break
case 0:break
default :break
}
}
void add()/*添加函数*/
{
FILE*fp
int n
int count=0
int i
int m=load()
printf("\n 原来的职工信息:\n")
display()/* 调用浏览函数*/
printf("\n")
fp=fopen("emploee_list","a")
printf("请输入想增加的职工数:\n")
scanf("%d",&n)
for (i=mi<(m+n)i++)
{
printf("\n 请输入新增加职工的信息:\n")
printf("请输入职工号: ")
srand((int)time(0))
em[i].num=rand()%10000+20000000
if(em[i].num!=em[i-1].num)
printf("%8d ",em[i].num)
printf("\n")
printf("请输入姓名: ")
scanf("%s",em[i].name)
getchar()
printf("请输入性别(f--女 m--男): ")
scanf("%c",&em[i].sex)
printf("请输入年龄: ")
scanf("%d",&em[i].age)
printf("请输入学历: ")
scanf("%s",em[i].xueli)
printf("请输入工资: ")
scanf("%d",&em[i].wage)
printf("请输入住址: ")
scanf("%s",em[i].addr)
printf("请输入电话: ")
scanf("%d",&em[i].tel)
printf("\n")
count=count+1
printf("已增加的人数:\n")
printf("%d\n",count)
}
printf("\n添加完毕!\n")
m=m+count
printf("\n浏览增加后的所有职工信息:\n")
printf("\n")
save(m)
display()
fclose(fp)
}
void search()/*查询函数*/
{
int t,flag
do
{
printf("\n按职工号查询请按1 按学历查询请按2 按电话号码查询请按3,进入主函数按4\n")
scanf("%d",&t)
if(t>=1&&t<=4)
{
flag=1
break
}
else
{
flag=0
printf("您输入有误,请重新选择!")
}
}
while(flag==0)
while(flag==1)
{
switch(t)
{
case 1:printf("按职工号查询\n")search_num()break
case 2:printf("按学历查询\n")search_xueli()break
case 3:printf("按电话号码查询\n")search_tel()break
case 4:main()break
default:break
}
}
}
void search_num()
{
int num
int i,t
int m=load()
printf("请输入要查找的职工号(20001111---20009999):\n")
scanf("%d",&num)
for(i=0i<mi++)
if(num==em[i].num)
{
printf("\n已找到此人,其记录为:\n")
printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n")
printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel)
break
}
if(i==m)
printf("\n对不起,查无此人\n")
printf("\n")
printf("返回查询函数请按1,继续查询职工号请按2\n")
scanf("%d",&t)
switch(t)
{
case 1:search()break
case 2: break
default:break
}
}
void search_xueli()
{
char xueli[30]
int i,t
int m=load()
printf("请输入要查找的学历:\n")
scanf("%s",xueli)
for(i=0i<mi++)
if(strcmp(em[i].xueli,xueli)==0)
{
printf("\n已找到,其记录为:\n")
printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n")
printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel)
}
if(i==m)
printf("\n对不起,查无此人\n")
printf("\n")
printf("返回查询函数请按1,继续查询学历请按2\n")
scanf("%d",&t)
switch(t)
{
case 1:search()break
case 2:break
default :break
}
}
void search_tel()
{
long int tel
int i, t
int m=load()
printf("请输入要查找的电话号码:\n")
scanf("%ld",&tel)
for(i=0i<mi++)
if(tel==em[i].tel)
{
printf("\n已找到此人,其记录为:\n")
printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n")
printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel)
break
}
if(i==m)
printf("\n对不起,查无此人\n")
printf("\n")
printf("返回查询函数请按1,继续查询电话号码请按2\n")
scanf("%d",&t)
switch(t)
{
case 1:search()break
case 2:break
default :break
}
}
void modify() /*修改函数*/
{
int num
char name[10]
char sex
int age
char xueli[30]
int wage
char addr[30]
long int tel
int b,c,i,n,t,flag
int m=load()/*导入文件内的信息*/
printf("\n 原来的职工信息:\n")
display()/* 调用浏览函数*/
printf("\n")
printf("请输入要修改的职工的姓名:\n")
scanf("%s",name)
for(flag=1,i=0flag&&i<mi++)
{
if(strcmp(em[i].name,name)==0)
{
printf("\n已找到此人,原始记录为:\n")
printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n")
printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel)
printf("\n确实要修改此人信息请按1 不修改请按0\n")
scanf("%d",&n)
if(n==1)
{
printf("\n需要进行修改的选项\n 1.职工号 2.姓名 3.性别 4.年龄 5.学历 6.工资 7.住址 8.电话\n")
printf("请输入你想修改的那一项序号:\n")
scanf("%d",&c)
if(c>8||c<1)
printf("\n选择错误,请重新选择!\n")
}
flag=0
}
}
if(flag==1)
printf("\n对不起,查无此人!\n")
do
{
switch(c) /*因为当找到第i个职工时,for语句后i自加了1,所以下面的应该把改后的信息赋值给第i-1个人*/
{
case 1:printf("职工号改为: ")
scanf("%d",&num)
em[i-1].num=num
break
case 2:printf("姓名改为: ")
scanf("%s",name)
strcpy(em[i-1].name,name)
break
case 3:printf("性别改为: ")
getchar()
scanf("%c",&sex)
em[i-1].sex=sex
break
case 4:printf("年龄改为: ")
scanf("%d",&age)
em[i-1].age=age
break
case 5:printf("学历改为: ")
scanf("%s",xueli)
strcpy(em[i-1].xueli,xueli)
break
case 6:printf("工资改为: ")
scanf("%d",wage)
break
case 7:printf("住址改为: ")
scanf("%s",addr)
strcpy(em[i-1].addr,addr)
break
case 8:printf("电话改为: ")
scanf("%ld",&tel)
em[i-1].tel=tel
break
}
printf("\n")
printf("\n是否确定所修改的信息?\n 是 请按1 不,重新修改 请按2: \n")
scanf("%d",&b)
}
while(b==2)
printf("\n浏览修改后的所有职工信息:\n")
printf("\n")
save(m)
display()
printf("\n继续修改请按1,不再修改请按0\n")
scanf("%d",&t)
switch(t)
{
case 1:modify()break
case 0:break
default :break
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)