libxlsxwriter数据验证

news2024/11/23 11:56:37

今天要分享的这个问题其实也属于excel的高级用法。我们想通过libxlsxwriter来实现一个能对用户的输入进行数据验证的表格功能。

内心os:小白最近是不是有点走火入魔了……我们真的会遇上这样的场景吗:需要通过代码生成一个表格,这个表格中还有若干需要潜在用户输入的单元格,并且还要对这些单元格做数据有效性验证!且不管这个需求是不是很少遇到,就当小白在这里钻了一个技术的牛角尖。

1 例程学习

小白最近特别直率,二话不说,先上例程(扒自libxlsxwriter官方例程,小白进行了中文改造):

#include "xlsxwriter.h"
#include <iostream>
#include <wchar.h>
#include <windows.h>

using std::string;

string GBKToUTF8(const char* strGBK)
{
	int len = MultiByteToWideChar(CP_ACP, 0, strGBK, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, strGBK, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	string strTemp = str;
	if (wstr) delete[] wstr;
	if (str) delete[] str;
	return strTemp;
}

string UTF8ToGBK(const char* strUTF8)
{
	int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, NULL, 0);
	wchar_t* wszGBK = new wchar_t[len + 1];
	memset(wszGBK, 0, len * 2 + 2);
	MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, wszGBK, len);
	len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
	char* szGBK = new char[len + 1];
	memset(szGBK, 0, len + 1);
	WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
	string strTemp(szGBK);
	if (wszGBK) delete[] wszGBK;
	if (szGBK) delete[] szGBK;
	return strTemp;
}

 /*
  * 向excel表中写入数据,这些数据用来为后续做合法性判断作辅助作用.
  */
void write_worksheet_data(lxw_worksheet* worksheet, lxw_format* format) {


    worksheet_write_string(worksheet, CELL("A1"),
        GBKToUTF8("使用libxlsxwriter进行数据验证").data(),
        format);
    worksheet_write_string(worksheet, CELL("B1"), GBKToUTF8("向此列中输入值").data(), format);
    worksheet_write_string(worksheet, CELL("D1"), GBKToUTF8("示例数据").data(), format);

    worksheet_write_string(worksheet, CELL("D3"), GBKToUTF8("整数").data(), NULL);
    worksheet_write_number(worksheet, CELL("E3"), 1, NULL);
    worksheet_write_number(worksheet, CELL("F3"), 10, NULL);

    worksheet_write_string(worksheet, CELL("D4"), GBKToUTF8("列表数据").data(), NULL);
    worksheet_write_string(worksheet, CELL("E4"), GBKToUTF8("开").data(), NULL);
    worksheet_write_string(worksheet, CELL("F4"), GBKToUTF8("高").data(), NULL);
    worksheet_write_string(worksheet, CELL("G4"), GBKToUTF8("关").data(), NULL);

    worksheet_write_string(worksheet, CELL("D5"), GBKToUTF8("公式").data(), NULL);
    worksheet_write_formula(worksheet, CELL("E5"), "=AND(F5=50,G5=60)", NULL);
    worksheet_write_number(worksheet, CELL("F5"), 50, NULL);
    worksheet_write_number(worksheet, CELL("G5"), 60, NULL);

}

/*
 * 创建一个带有数据合法性验证的数据表
 */
int main() {

    lxw_workbook* workbook = workbook_new("data_validate1.xlsx");
    lxw_worksheet* worksheet = workbook_add_worksheet(workbook, NULL);

    // 定义一个验证变量
    lxw_data_validation* data_validation = (lxw_data_validation*)calloc(1, sizeof(lxw_data_validation));

    /* 创建带颜色强调的表头格式 */
    lxw_format* format = workbook_add_format(workbook);
    format_set_border(format, LXW_BORDER_THIN);
    format_set_fg_color(format, 0xC6EFCE);
    format_set_bold(format);
    format_set_text_wrap(format);
    format_set_align(format, LXW_ALIGN_VERTICAL_CENTER);
    format_set_indent(format, 1);
    format_set_font_name(format, "SimSun");

	/* 创建带颜色强调的表头格式 */
	lxw_format* format1 = workbook_add_format(workbook);
	format_set_border(format1, LXW_BORDER_THIN);
	format_set_align(format1, LXW_ALIGN_VERTICAL_CENTER);
	format_set_font_name(format1, "SimHei");

    /* 向表中写入一些辅助数据 */
    write_worksheet_data(worksheet, format);

    /* 设置数据表中的列宽等页面数据 */
    worksheet_set_column(worksheet, 0, 0, 70, NULL);
    worksheet_set_column(worksheet, 1, 1, 22, NULL);
    worksheet_set_column(worksheet, 3, 3, 15, NULL);
    worksheet_set_row(worksheet, 0, 36, NULL);


    /*
     * 例1:向表中输入一个范围值
     */
    worksheet_write_string(worksheet,
        CELL("A3"),
        GBKToUTF8("输入一个1到10之间的整数").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 1;
    data_validation->maximum_number = 10;

    worksheet_data_validation_cell(worksheet, CELL("B3"), data_validation);


    /*
     * 例2:向表中输入一个范围之外的值
     */
    worksheet_write_string(worksheet,
        CELL("A5"),
        GBKToUTF8("输入一个不在1到10之间的整数(1和10由单元格E3和F3指定)").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_NOT_BETWEEN;
    data_validation->minimum_formula = "=E3";
    data_validation->maximum_formula = "=F3";

    worksheet_data_validation_cell(worksheet, CELL("B5"), data_validation);


    /*
     * 例3:向表中输入一个大于某值的数
     */
    worksheet_write_string(worksheet,
        CELL("A7"),
        GBKToUTF8("输入一个比0大的整数").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
    data_validation->value_number = 0;

    worksheet_data_validation_cell(worksheet, CELL("B7"), data_validation);


    /*
     * 例4:向表中输入一个小于某值的数
     */
    worksheet_write_string(worksheet,
        CELL("A9"),
        GBKToUTF8("输入一个比10小的整数").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_LESS_THAN;
    data_validation->value_number = 10;

    worksheet_data_validation_cell(worksheet, CELL("B9"), data_validation);


    /*
     * 例5:限制输入为一个范围内的小数
     */
    worksheet_write_string(worksheet,
        CELL("A11"),
        GBKToUTF8("请输入一个在0.1到0.5之间的小数").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_DECIMAL;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 0.1;
    data_validation->maximum_number = 0.5;

    worksheet_data_validation_cell(worksheet, CELL("B11"), data_validation);


    /*
     * 例6:限制输入为下拉列表中的值
     */
    worksheet_write_string(worksheet,
        CELL("A13"),
        GBKToUTF8("从下拉列表中选择一个值").data(),
        format1);

    char temp1[16] = "";
    sprintf_s(temp1, GBKToUTF8("开").data());
	char temp2[16] = "";
	sprintf_s(temp2, GBKToUTF8("高").data());
	char temp3[16] = "";
	sprintf_s(temp3, GBKToUTF8("关").data());

    char* list[] = {
        temp1,
        temp2,
        temp3,
        NULL };

    data_validation->validate = LXW_VALIDATION_TYPE_LIST;
    data_validation->value_list = list;

    worksheet_data_validation_cell(worksheet, CELL("B13"), data_validation);


    /*
     * 例7:限制输入为下拉列表的值(下拉列表由单元格指定)
     */
    worksheet_write_string(worksheet,
        CELL("A15"),
        GBKToUTF8("在下拉列表中选择一个值(下拉列表中的值来自单元格指定)").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_LIST_FORMULA;
    data_validation->value_formula = "=$E$4:$G$4";

    worksheet_data_validation_cell(worksheet, CELL("B15"), data_validation);


    /*
     * 例8:限制输入为指定范围内的日期
     */
    worksheet_write_string(worksheet,
        CELL("A17"),
        GBKToUTF8("输入一个 1/1/2008 和 12/12/2008 之间的日期").data(),
        format1);

    lxw_datetime datetime1 = { 2008,  1,  1, 0, 0, 0 };
    lxw_datetime datetime2 = { 2008, 12, 12, 0, 0, 0 };

    data_validation->validate = LXW_VALIDATION_TYPE_DATE;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_datetime = datetime1;
    data_validation->maximum_datetime = datetime2;

    worksheet_data_validation_cell(worksheet, CELL("B17"), data_validation);


    /*
     * 例9:输入指定范围内的时间
     */
    worksheet_write_string(worksheet,
        CELL("A19"),
        GBKToUTF8("输入 6:00 和 12:00之间的时间").data(),
        format1);

    lxw_datetime datetime3 = { 0, 0, 0,  6, 0, 0 };
    lxw_datetime datetime4 = { 0, 0, 0, 12, 0, 0 };

    data_validation->validate = LXW_VALIDATION_TYPE_DATE;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_datetime = datetime3;
    data_validation->maximum_datetime = datetime4;

    worksheet_data_validation_cell(worksheet, CELL("B19"), data_validation);


    /*
     * 例10:限制输入的字符比指定的长度要长
     */
    worksheet_write_string(worksheet,
        CELL("A21"),
        GBKToUTF8("输入一个比3个字符长的字符串").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_LENGTH;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
    data_validation->value_number = 3;

    worksheet_data_validation_cell(worksheet, CELL("B21"), data_validation);


    /*
     * 例11:基于公式来限制输入.
     */
    worksheet_write_string(worksheet,
        CELL("A23"),
        GBKToUTF8("如果以下为真则允许输入一个值 \"=AND(F5=50,G5=60)\"").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_CUSTOM_FORMULA;
    data_validation->value_formula = "=AND(F5=50,G5=60)";

    worksheet_data_validation_cell(worksheet, CELL("B23"), data_validation);


    /*
     * 例12:为数据验证显示提示信息
     */
    worksheet_write_string(worksheet,
        CELL("A25"),
        GBKToUTF8("选中此单元格时显示提示").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 1;
    data_validation->maximum_number = 100;
    data_validation->input_title = const_cast<char*>(GBKToUTF8("输入一个整数值:").c_str());
    data_validation->input_message = const_cast<char*>(GBKToUTF8("在1到100之间").c_str());

    worksheet_data_validation_cell(worksheet, CELL("B25"), data_validation);


    /*
     * 例13:输入错误时以错误对话框弹出提示
     */
    worksheet_write_string(worksheet,
        CELL("A27"),
        GBKToUTF8("当输入的值不在1到100之间时显示一个错误对话框").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 1;
    data_validation->maximum_number = 100;
    data_validation->input_title = const_cast<char*>(GBKToUTF8("输入一个整数值:").c_str());
    data_validation->input_message = const_cast<char*>(GBKToUTF8("在1到100之间").c_str());
    data_validation->error_title = const_cast<char*>(GBKToUTF8("输入的值不合法").c_str());
    data_validation->error_message = const_cast<char*>(GBKToUTF8("输入的值必须在1到100之间").c_str());

    worksheet_data_validation_cell(worksheet, CELL("B27"), data_validation);


    /*
     * 例14:输入错误时以提示对话框进行提示
     */
    worksheet_write_string(worksheet,
        CELL("A29"),
        GBKToUTF8("当输入的值不在1到100之间时显示一个提示对话框").data(),
        format1);

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 1;
    data_validation->maximum_number = 100;
    data_validation->error_type = LXW_VALIDATION_ERROR_TYPE_INFORMATION;
    data_validation->input_title = const_cast<char*>(GBKToUTF8("输入一个整数值:").c_str());
    data_validation->input_message = const_cast<char*>(GBKToUTF8("在1到100之间").c_str());
    data_validation->error_title = const_cast<char*>(GBKToUTF8("输入的值不合法").c_str());
    data_validation->error_message = const_cast<char*>(GBKToUTF8("输入的值必须在1到100之间").c_str());
    //

    worksheet_data_validation_cell(worksheet, CELL("B29"), data_validation);


    /* 清理. */
    free(data_validation);

    return workbook_close(workbook);
}

由于内容比较多,所以我们不直接上效果图了,在第2小节里慢慢掰开了讲。

2 关键提要

这次的例程比较,额,长。
因为这里面其实一共有14个例子。
但是这14个例子又有很强的重复性,因此它仍然是“一个”例程,而不是“14个”例程。

读者朋友们请先忽略例程头部的两个转码函数,这只是为了适用中文,小白冥思苦想的下策。关于这个问题小白也已经有专门文章有过解释,不明白的同学可以移步libxlsxwriter中文报错问题。小白在下面讲到这里的转码时也会再进行解释。

2.1 验证值的输入范围(例1-例5)

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 1;
    data_validation->maximum_number = 10;

    worksheet_data_validation_cell(worksheet, CELL("B3"), data_validation);

最简单的应用就是通过限定值的输入范围来控制输入:
worksheet_data_validation_cell 作为最终对数据验证作用的单元格起作用的函数;
另一个函数为worksheet_data_validation_range,可以令数据验证对多个单元格起作用。

对例1来说,data_validation->validate表示的是验证的类型,这里选择LXW_VALIDATION_TYPE_INTEGER表示是整数型值验证。
data_validation->criteria表示的是验证的规则,这里选择LXW_VALIDATION_CRITERIA_BETWEEN表示“介于两个数之间”。
正因如此,以下指定上、下限:
data_validation->minimum_number即下限为1;
data_validation->maximum_number即上限为10。

于是例1 实际上就是在限制B3这个单元格的输入需要在1-10之间的整数,其他的输入皆为非法。

在这里插入图片描述

可见,当输入11时,就会弹出错误框提示不合法。

例2 其实和例1很相似,但有两个区别:

  • 例1是“介于两个数之间”,例2是“不介于两个数之间”;
  • 例2的上下限数值通过单元格中的数据来进行限制。
	data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_NOT_BETWEEN;
    data_validation->minimum_formula = "=E3";
    data_validation->maximum_formula = "=F3";

通过设置的参数可以看到,指定上下限的变量变成了minimum_formulamaximum_formula.分别指定Excel表格中的两个单元格,以其内容作为限定的上下限。
此时输入5,则为非法,一样弹出错误框提示。

在这里插入图片描述

例3 更简单,判断是不是需要比某个值更大。

	data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
    data_validation->value_number = 0;

可以看到,criteria变成了LXW_VALIDATION_CRITERIA_GREATER_THAN
value_number设置为0。即需要输入数比0大。
效果图就不贴了,因为太简单。

例4跟例3相类似。

	data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_LESS_THAN;
    data_validation->value_number = 10;

没啥要多说的,criteria变成了LXW_VALIDATION_CRITERIA_LESS_THAN.

例5输入的是小数

    data_validation->validate = LXW_VALIDATION_TYPE_DECIMAL;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 0.1;
    data_validation->maximum_number = 0.5;

注意validate的类型变了,变成了LXW_VALIDATION_TYPE_DECIMAL.
这也没啥要多说的,非常简单,不想贴图了。(小白最近加班有点过头,允许偷个懒)

2.2 提供下拉列表来限定输入范围(例6-例7)

oops,这里插入一则小白的炫耀帖(请允许本小白无法平抑有点激动的心情):在例7中小白找到了github代码中的一处bug,已经在github上跟libxlsxwriter的作者反馈(by xiaobai’s poor English)并得到了修改,这是小白的first issue in github. 传送门:围观可以,不要说话

本篇的重头戏来了。例6和例7,小白替大家连踩两坑,希望此处有点掌声(六个项目压在身上,早8晚9,晚上还在踩坑的小白是什么精神555555~)。

例6的坑不是由于libxlsxwriter本身引起的,纯纯的中文编码问题。

/*
     * 例6:限制输入为下拉列表中的值
     */
    worksheet_write_string(worksheet,
        CELL("A13"),
        GBKToUTF8("从下拉列表中选择一个值").data(),
        format1);

    char temp1[16] = "";
    sprintf_s(temp1, GBKToUTF8("开").data());
	char temp2[16] = "";
	sprintf_s(temp2, GBKToUTF8("高").data());
	char temp3[16] = "";
	sprintf_s(temp3, GBKToUTF8("关").data());

    char* list[] = {
        temp1,
        temp2,
        temp3,
        NULL };

    data_validation->validate = LXW_VALIDATION_TYPE_LIST;
    data_validation->value_list = list;

    worksheet_data_validation_cell(worksheet, CELL("B13"), data_validation);

这里小白用了一个非常蹩脚的方式在做编码的转换,无奈,既要适应windows这位大爷的GBK程序源码编码,又要适应最终目标——office excel这位大爷的utf8编码格式。只能出此下策。
而且这里组合list的时候需要注意,末尾需要以一个NULL结尾。特别要注意的是,小白用了sprintf_s函数来生成字符串,而不是在list的定义那里直接赋值(因为会失败),想要尝试的同学也可以自己改一下看,看这个坑摔得疼不疼。
所以很可能小白采取的这一种折中的方式是唯一可行的方案。。。丑你也得接受一下。

下拉列表的效果图如下:
在这里插入图片描述

例7的坑小白已经用身躯帮大家填平了,现在大家直接去官网上看例程,bug已经修复(当然本篇博客中的代码也是没有bug的安全代码)。
原始代码中主要的错误为:
data_validation->validate = LXW_VALIDATION_TYPE_LIST;
这样赋值其实是不对的,但如果你是在例6的后面运行例7,很难发现这个错误,因为例6的值会影响到例7,而他们的下拉列表内容又一样,会生成一个看似正确的下拉列表。(正因为如此这个坑才这样难发现,但是如果你是按照错误的方式写的,你会发现无论怎么修改对应单元格中的内容,下拉列表的值都不会发生变化)。

	data_validation->validate = LXW_VALIDATION_TYPE_LIST_FORMULA;
    data_validation->value_formula = "=$E$4:$G$4";

例7和例6的最大差别在于validate类型不同,设定后对应到value_formula赋值。
可以看下效果图,这里小白把对应单元格中的值做了修改,看到下拉列表与单元格内容是匹配的。
在这里插入图片描述

2.3 限定时间和日期输入(例8-例9)

例8和例9是进行了时间和日期的限定输入。
先看例8,注意lxw_datetime的格式输入法。其他很简单。同上,不贴效果图。

	lxw_datetime datetime1 = { 2008,  1,  1, 0, 0, 0 };
    lxw_datetime datetime2 = { 2008, 12, 12, 0, 0, 0 };

    data_validation->validate = LXW_VALIDATION_TYPE_DATE;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_datetime = datetime1;
    data_validation->maximum_datetime = datetime2;

再看例9,与例8仅有一点技巧,就是如何表示时间:表示日期的年月日全写0就好。

    lxw_datetime datetime3 = { 0, 0, 0,  6, 0, 0 };
    lxw_datetime datetime4 = { 0, 0, 0, 12, 0, 0 };

    data_validation->validate = LXW_VALIDATION_TYPE_DATE;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_datetime = datetime3;
    data_validation->maximum_datetime = datetime4;

同上,此处不贴效果图。

2.4 限定输入的字符长度(例10)

例10的玩法有点适合英文。因为字符长度的计算,对于中文编码来说会有点混乱(小白已经在此事上吃了多少亏了,唉)。

	data_validation->validate = LXW_VALIDATION_TYPE_LENGTH;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
    data_validation->value_number = 3;

也没啥好注意的,validate的类型是LXW_VALIDATION_TYPE_LENGTH罢了。
一样,不用贴效果图。

2.5 基于公式来限定输入(例11)

例11有点像一个开关控制。如果公式表达式为true,则允许输入,反之则不允许输入。

	data_validation->validate = LXW_VALIDATION_TYPE_CUSTOM_FORMULA;
    data_validation->value_formula = "=AND(F5=50,G5=60)";

唯一需要注意的是这个类型的写法LXW_VALIDATION_TYPE_CUSTOM_FORMULA.
此例中是需要F5单元格中为50,G5单元格中为60同时成立才允许输入。

2.6 为数据输入提供提示(例12-例14)

例12到例14是带有输入提示信息的验证。
例12中添加了input_titleinput_message两个变量的控制,分别表示提示框的标题,以及提示框的内容。需要注意的是这两者都有长度限制,不能过长。具体是多长参看文档,小白也不记得,这似乎不是很重要(谁会写一个太长的提示呢)

    data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
    data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
    data_validation->minimum_number = 1;
    data_validation->maximum_number = 100;
    data_validation->input_title = const_cast<char*>(GBKToUTF8("输入一个整数值:").c_str());
    data_validation->input_message = const_cast<char*>(GBKToUTF8("在1到100之间").c_str());

效果展示一下:

在这里插入图片描述

例13比例12多出了error_titleerror_message

    data_validation->error_title = const_cast<char*>(GBKToUTF8("输入的值不合法").c_str());
    data_validation->error_message = const_cast<char*>(GBKToUTF8("输入的值必须在1到100之间").c_str());

效果图贴一下,注意弹出的是错误提示框。
在这里插入图片描述

例14比例13只多出一样,但小白发现如果是中文编码时,一定要保证先定义error_type,否则会报错,这应该又是编码的锅。

	data_validation->error_type = LXW_VALIDATION_ERROR_TYPE_INFORMATION;
    data_validation->input_title = const_cast<char*>(GBKToUTF8("输入一个整数值:").c_str());
    data_validation->input_message = const_cast<char*>(GBKToUTF8("在1到100之间").c_str());
    data_validation->error_title = const_cast<char*>(GBKToUTF8("输入的值不合法").c_str());
    data_validation->error_message = const_cast<char*>(GBKToUTF8("输入的值必须在1到100之间").c_str());

贴下效果图,注意错误发生时提示框是一个信息提示而不是一个错误提示,这是与例13的区别。
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/346881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧机场,或将成为航空领域数字孪生技术得完美应用

在《智慧民航建设路线图》文件中&#xff0c;民航局明确指出&#xff0c;智慧机场是实现智慧民航的四个核心抓手之一。这一战略性举措旨在推进数字化技术与航空产业的深度融合&#xff0c;为旅客提供更加智能化、便捷化、安全化的出行服务&#xff0c;进一步提升我国民航发展的…

IO流进阶

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录IO流进阶缓冲流缓冲流概述字节缓冲流(…

【LeetCode】剑指 Offer(1)

目录 写在前面&#xff1a; 题目1&#xff1a;剑指 Offer 03. 数组中重复的数字 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目2&#xff1a;剑指 Offer 06. 从…

JavaEE初阶---TCP/IP协议

一:概述 本文是网络编程的理论基础,也是网络部分的重点和难点,在笔试,面试中,这部分内容也多有考察.二:详解 TCP/IP五层协议 应用层传输层网络层数据链路层物理层 2.1应用层 我们自己编写的代码,就是在应用层,这也是在实际开发中接触最多的层.应用层里有许多现成的协议 , 而在…

springboot(5)静态资源访问前缀+欢迎页+REST风格的传递参数

Springboot的访问规则是 先访问controller的请求&#xff0c;如果没有的话&#xff0c;我们在访问静态资源。 但是静态资源过多的情况下这样不好处理&#xff0c;所以我们可以加一个前缀&#xff0c;这样可以拦截掉非静态资源的请求&#xff0c;每次都可以准确快速无风险的访…

镀镍废水处理,企业污水处理,离子交换树脂在镀镍废水中的应用

传统沉淀法不能满足日益提的环保要求(如电镀表三镍含量要求0.1mg/l以下)。针对特定重金属离子的特点&#xff0c;利用螯合树脂的特种功能基团与重金属离子形成络合物的特性&#xff0c;实现重金属离子的回收利用及深度去除。 CH-90Na对除铜镍铅锌钴锰等具有特定的选择性&#x…

API的应用

API&#xff08;Application Programming Interface,应用程序编程接口&#xff09;是一些预先定义的函数&#xff0c;目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力&#xff0c;而又无需访问源码&#xff0c;或理解内部工作机制的细节 应用程序接口 想…

安卓|aar和jar打包引入流程演示

安卓|aar和jar打包引入流程演示aar和jar存在相关意义打包环境工具aar和jar|Module项目目录aar打包|引入总览步骤|aar配置打包创建java or kotlin类文件及资源|截图展示步骤|aar包引入jar打包|引入总览步骤|jar配置打包任务创建java类文件|截图展示步骤|jar包引入aar和jar运行在…

OpenTracing协议规范链接

一、官网链接 OpenTracing specificationhttps://opentracing.io/specification/不过目前OpenTracing项目已归档&#xff0c;不再维护。需要参考OpenTelemetry官网链接 Migrating from OpenTracing | OpenTelemetryBackward compatibility with OpenTracing has been a prior…

Promise 的理解

promise 是什么&#xff1f;promise 是JS 中进行异步编程的最新的解决方案从语法上来说&#xff1a;Promise 是一个构造函数从功能上来说&#xff1a;promise 对象时用来封装一个异步操作并可以获取其结果其三种状态&#xff0c;reasolve 、pendding、 rejectedPromise 的基本运…

计算机网络-ip数据报

在图中&#xff0c;网络层包含了四种协议&#xff1a;ARP、IP、ICMP、IGMP&#xff0c;由上下关系表明&#xff0c;ARP为IP协议服务&#xff0c;IP为ICMP和IGMP服务。 IP数据报格式 此处不区分数据报和分组的概念&#xff1a;当数据部分过长时&#xff0c;将数据部分拆分&…

2022年全国职业院校技能大赛A(1)

目录 模块A 基础设施设置与安全加固 一、项目和任务描述&#xff1a; 二、服务器环境说明 三、具体任务&#xff08;每个任务得分以电子答题卡为准&#xff09; A-1任务一 登录安全加固 1.密码策略&#xff08;Windows&#xff0c;Linux&#xff09; a.设置最短密码长度为…

Python 之 NumPy 随机函数和常用函数

文章目录一、随机函数1. numpy.random.rand(d0,d1,…,dn)2. numpy.random.randn(d0,d1,…,dn)3. numpy.random.normal()4. numpy.random.randint()5. numpy.random.sample6. 随机种子np.random.seed()7. 正态分布 numpy.random.normal二、数组的其他函数1. numpy.resize()2. nu…

芯片是怎样“炼”成的?

在芯片设计完成&#xff0c;交由芯片制造厂&#xff08;Fab&#xff09;进行试产&#xff08;Tape out&#xff09;之后&#xff0c;就可以进行量产了。但Tape out是个漫长的过程&#xff0c;在此过程中&#xff0c;Fab里的工艺及设备工程师们需要不断调试&#xff0c;使得芯片…

Python优化算法—遗传算法

Python优化算法—遗传算法一、前言二、安装三、遗传算法3.1 自定义函数3.2 遗传算法进行整数规划3.3 遗传算法用于旅行商问题3.4 使用遗传算法进行曲线拟合一、前言 优化算法&#xff0c;尤其是启发式的仿生智能算法在最近很火&#xff0c;它适用于解决管理学&#xff0c;运筹…

全球认可的PMI认证体系

全球认可的PMI认证体系我们生活在一个“项目化”的世界里&#xff0c;而且这一趋势在不断加强。PMI的专业认证将使您做好准备&#xff0c;满足全球范围内各种项目、不同企业的需求。PMI的认证源于项目管理从业者&#xff0c;并服务于项目管理从业者。所有认证基于严格的标准和持…

HTML5之CSS基础学习笔记

基础认知 CSS初始 CSS的介绍 CSS&#xff1a;层叠样式表&#xff08;Cascading style sheets&#xff09; CSS作用是什么&#xff1f;&#xff1f; 给页面中的HTML标签设置样式 CSS就是用来做美化的&#xff0c;我之前写的网页就是黑白&#xff0c;要不带点彩色的图片&#x…

MYSQL-主从复制

文章目录1 概述2 原理3 搭建3.1 主库配置3.2 从库配置1 概述 主从复制是指将主数据库的DDL和 DML操作通过二进制日志传到从库服务器中&#xff0c;然后在从库上对这些日志重新执行(也叫重做)&#xff0c;从而使得从库和主库的数据保持同步。 MySQL支持一台主库同时向多台从库进…

从事架构师岗位快2年了,聊一聊我对架构的一些感受和看法

从事架构师岗位快2年了&#xff0c;聊一聊我和ChatGPT对架构的一些感受和看法 职位不分高低&#xff0c;但求每天都能有新的进步&#xff0c;永远向着更高的目标前进。 文章目录踏上新的征程架构是什么&#xff1f;架构师到底是干什么的&#xff1f;你的终极目标又是什么&#…

腾讯实践:面向在线游戏的智能推荐系统设计实践

‍省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2023年1月份热门报告合集ChatGPT的发展历程、原理、技术架构及未来方向《ChatGPT&#xff1a;真格基金分享.pdf》2023年AIGC发展趋势报告&#xff1a;人工智能的下一时代推荐…