MFC列表框示例
本文仅供学习交流,严禁用于商业用途,如本文涉及侵权请及时联系本人将于及时删除
目录
1.示例内容
2.程序步骤
3.运行结果
4.代码全文
1.示例内容
编写一个对话框应用程序CMFC_Li6_4_学生信息Dlg,对话框中有一个列表框,当用户单击列表框中的一个列表项(一位学生)时,在5个编辑框中分别显示这个学生的姓名、学号、性别、年龄及班级,外加一个下拉框用于选择显示学制。单击添加按钮时,“姓名”编辑框中的文本将被添加到列表框中(用于作为索引);选中列表框中某一列表项,单击删除按钮时,当前的列表项将被删除。
2.程序步骤
(1) 创建基于对话框的应用程序CMFC_Li6_4_学生信息Dlg,将对话框的Caption改为“学生信息”。
并布局对话框控件。
(2) 删除对话框模板中的静态文本及“确定”按钮,将“取消”按钮的Caption改为“退出”。添加如上图所示的控件,并利用ClassWizard类向导为有关控件添加关联成员变量,如下表所示。
(3)打开MFC_Li6_4_学生信息Dlg.h头文件,在对话框类CLCBoxDlg中定义一个结构体类型student,用于声明与列表项关联的数据项。
private:struct student{CString name;long number;CString sex;int age;CString classno;CString xuezhi;};
public:student stu[5];int i=0;//用于控制stu[]数组下标
(4) 利用ClassWizard类向导在对话框类MFC_Li6_4_学生信息Dlg中为“添加”与“删除”按钮添加消息BN_CLICKED的处理函数,并添加代码。单击“添加”按钮时,如果编辑的“姓名”是一个新项,则向列表框添加该项。单击“删除”按钮将删除列表框中当前的列表项。
void CMFC_Li6_4_学生信息Dlg::OnBnClickedAdd()
{// TODO: 在此添加控件通知处理程序代码UpdateData(true); //获得控件中的数据if (m_name.IsEmpty())//判断“姓名”是否为空{MessageBox(_T("学生姓名不能为空!"));return;}m_name.TrimLeft(); //去掉姓名左边的空格m_name.TrimRight(); //去掉姓名右边的空格m_class.TrimLeft();m_class.TrimRight();m_sex.TrimLeft();m_sex.TrimRight();if ((m_list.FindStringExact(-1, m_name)) != LB_ERR) //从头至尾找{MessageBox(_T("列表框中已有该项,不能再添加!"));return;}int nIndex = m_list.AddString(m_name); //向列表框添加学生姓名//student stu; //将学生数据项与新增的列表项关联起来stu[i].name = m_name;stu[i].number = m_number;stu[i].sex = m_sex;stu[i].age = m_age;stu[i].classno = m_class;stu[i].xuezhi = m_xuezhi;//m_list.SetItemDataPtr(nIndex, new student(stu)); //建立关联m_list.SetItemDataPtr(nIndex, &stu[i].name); //建立关联i++;if (i > 4){return;}
} void CMFC_Li6_4_学生信息Dlg::OnBnClickedDelete()
{// TODO: 在此添加控件通知处理程序代码int nIndex = m_list.GetCurSel(); //获得当前列表项的索引if (nIndex != LB_ERR){//释放关联数据所占的内存空间//delete(student*)m_list.GetItemDataPtr(nIndex);m_list.GetItemDataPtr(nIndex);m_list.DeleteString(nIndex); //删除列表框当前选项m_name = m_class = m_sex = m_xuezhi = "";//设置编辑框控件数据m_number = m_age = 0;UpdateData(false); //在编辑框中显示数据}elseMessageBox(_T("没有选择列表项或列表框操作失败!"));}
(5)利用ClassWizard类向导为列表框添加消息LBN_SELCHANGE的处理函数,并添加代码。当在列表框中选中某位学生,即当前列表框中选择项发生改变时,在编辑框中显示该学生信息的相关信息。
void CMFC_Li6_4_学生信息Dlg::OnLbnDblclkList()
{// TODO: 在此添加控件通知处理程序代码int nIndex = m_list.GetCurSel(); //获得当前列表项的索引if (nIndex != LB_ERR){//释放关联数据所占的内存空间//delete(student*)m_list.GetItemDataPtr(nIndex);//m_list.DeleteString(nIndex); //删除列表框当前选项//m_name = m_class = m_sex = "";//设置编辑框控件数据//m_number = m_age = 0;m_list.GetItemDataPtr(nIndex);m_name = stu[nIndex].name;m_number = stu[nIndex].number;m_sex = stu[nIndex].sex;m_age = stu[nIndex].age;m_class = stu[nIndex].classno;m_xuezhi = stu[nIndex].xuezhi;UpdateData(false); //在编辑框中显示数据}elseMessageBox(_T("没有选择列表项或列表框操作失败!"));
}
(6) 编译、链接并运行程序。
3.运行结果
//本案例有些许bug,目前定义存储结构体数量为5,编辑框中的基本信息显示到列表框中时,列表框中对应的详细信息会倒序
4.代码全文
// MFC_Li6_4_学生信息Dlg.h : 头文件
//#pragma once
#include "afxwin.h"// CMFC_Li6_4_学生信息Dlg 对话框
class CMFC_Li6_4_学生信息Dlg : public CDialogEx
{
// 构造
public:CMFC_Li6_4_学生信息Dlg(CWnd* pParent = NULL); // 标准构造函数// 对话框数据enum { IDD = IDD_MFC_LI6_4__DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:
// CListBox m_list;
// CString m_name;long m_number;CString m_sex;int m_age;CString m_class;
private:struct student{CString name;long number;CString sex;int age;CString classno;CString xuezhi;};public:afx_msg void OnBnClickedAdd();afx_msg void OnBnClickedDelete();CString m_name;CListBox m_list;afx_msg void OnLbnDblclkList();student stu[5];int i=0;CString m_xuezhi;
};
// MFC_Li6_4_学生信息Dlg.cpp : 实现文件
//#include "stdafx.h"
#include "MFC_Li6_4_学生信息.h"
#include "MFC_Li6_4_学生信息Dlg.h"
#include "afxdialogex.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx
{
public:CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()// CMFC_Li6_4_学生信息Dlg 对话框CMFC_Li6_4_学生信息Dlg::CMFC_Li6_4_学生信息Dlg(CWnd* pParent /*=NULL*/): CDialogEx(CMFC_Li6_4_学生信息Dlg::IDD, pParent)/*, m_name(_T(""))*/, m_number(0), m_sex(_T("")), m_age(0), m_class(_T("")), m_name(_T("")), m_xuezhi(_T(""))
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CMFC_Li6_4_学生信息Dlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);// DDX_Control(pDX, IDC_LIST, m_list);// DDX_Control(pDX, IDC_NAME, m_name);DDX_Text(pDX, IDC_NUMBER, m_number);DDX_Text(pDX, IDC_SEX, m_sex);DDX_Text(pDX, IDC_AGE, m_age);DDX_Text(pDX, IDC_CLASS, m_class);DDX_Text(pDX, IDC_NAME, m_name);DDX_Control(pDX, IDC_LIST, m_list);DDX_CBString(pDX, IDC_COMBO, m_xuezhi);
}BEGIN_MESSAGE_MAP(CMFC_Li6_4_学生信息Dlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_ADD, &CMFC_Li6_4_学生信息Dlg::OnBnClickedAdd)ON_BN_CLICKED(IDC_DELETE, &CMFC_Li6_4_学生信息Dlg::OnBnClickedDelete)ON_LBN_DBLCLK(IDC_LIST, &CMFC_Li6_4_学生信息Dlg::OnLbnDblclkList)
END_MESSAGE_MAP()// CMFC_Li6_4_学生信息Dlg 消息处理程序BOOL CMFC_Li6_4_学生信息Dlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标// TODO: 在此添加额外的初始化代码return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}void CMFC_Li6_4_学生信息Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}
}// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。void CMFC_Li6_4_学生信息Dlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFC_Li6_4_学生信息Dlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}void CMFC_Li6_4_学生信息Dlg::OnBnClickedAdd()
{// TODO: 在此添加控件通知处理程序代码UpdateData(true); //获得控件中的数据if (m_name.IsEmpty())//判断“姓名”是否为空{MessageBox(_T("学生姓名不能为空!"));return;}m_name.TrimLeft(); //去掉姓名左边的空格m_name.TrimRight(); //去掉姓名右边的空格m_class.TrimLeft();m_class.TrimRight();m_sex.TrimLeft();m_sex.TrimRight();if ((m_list.FindStringExact(-1, m_name)) != LB_ERR) //从头至尾找{MessageBox(_T("列表框中已有该项,不能再添加!"));return;}int nIndex = m_list.AddString(m_name); //向列表框添加学生姓名//student stu; //将学生数据项与新增的列表项关联起来stu[i].name = m_name;stu[i].number = m_number;stu[i].sex = m_sex;stu[i].age = m_age;stu[i].classno = m_class;stu[i].xuezhi = m_xuezhi;//m_list.SetItemDataPtr(nIndex, new student(stu)); //建立关联m_list.SetItemDataPtr(nIndex, &stu[i].name); //建立关联i++;if (i > 4){return;}
} void CMFC_Li6_4_学生信息Dlg::OnBnClickedDelete()
{// TODO: 在此添加控件通知处理程序代码int nIndex = m_list.GetCurSel(); //获得当前列表项的索引if (nIndex != LB_ERR){//释放关联数据所占的内存空间//delete(student*)m_list.GetItemDataPtr(nIndex);m_list.GetItemDataPtr(nIndex);m_list.DeleteString(nIndex); //删除列表框当前选项m_name = m_class = m_sex = m_xuezhi = "";//设置编辑框控件数据m_number = m_age = 0;UpdateData(false); //在编辑框中显示数据}elseMessageBox(_T("没有选择列表项或列表框操作失败!"));}void CMFC_Li6_4_学生信息Dlg::OnLbnDblclkList()
{// TODO: 在此添加控件通知处理程序代码int nIndex = m_list.GetCurSel(); //获得当前列表项的索引if (nIndex != LB_ERR){//释放关联数据所占的内存空间//delete(student*)m_list.GetItemDataPtr(nIndex);//m_list.DeleteString(nIndex); //删除列表框当前选项//m_name = m_class = m_sex = "";//设置编辑框控件数据//m_number = m_age = 0;m_list.GetItemDataPtr(nIndex);m_name = stu[nIndex].name;m_number = stu[nIndex].number;m_sex = stu[nIndex].sex;m_age = stu[nIndex].age;m_class = stu[nIndex].classno;m_xuezhi = stu[nIndex].xuezhi;UpdateData(false); //在编辑框中显示数据}elseMessageBox(_T("没有选择列表项或列表框操作失败!"));
}
【免费】MFC编写一个对话框应用程序CMFC-Li6-4-学生信息Dlg,对话框中有一个列表框,当用户单击列表框中的一个列表项(一位学生资源-CSDN文库
相关文章:

MFC列表框示例
本文仅供学习交流,严禁用于商业用途,如本文涉及侵权请及时联系本人将于及时删除 目录 1.示例内容 2.程序步骤 3.运行结果 4.代码全文 1.示例内容 编写一个对话框应用程序CMFC_Li6_4_学生信息Dlg,对话框中有一个列表框,当用户…...

Android TabLayout的简单用法
TabLayout 注意这里添加tab,使用binding.tabLayout.newTab()进行创建 private fun initTabs() {val tab binding.tabLayout.newTab()tab.text "模板库"binding.tabLayout.addTab(tab)binding.tabLayout.addOnTabSelectedListener(object : TabLayout.On…...
基于vite + pnpm monorepo 实现一个UI组件库
基于vite pnpm monorepo的vue组件库 仓库地址 思路 好多文章都是直接咔咔咔的上代码。跟着做也没问题,但总觉得少了些什么。下次做的时候还要找文章参考。。 需求有三个模块,那么就需要三个包。使用monorepo进行分包管理。 a. 组件库 b. 组件库文档…...

FDM3D打印系列——Luck13关节可动模型打印和各种材料的尝试
luck13可动关节模型FDM3D打印制作过程 大家好,我是阿赵。 最近我沉迷于打印一个叫做Luck13的关节超可动人偶。 首先说明一下,这个模型是分为了外甲和骨骼两个部分的。 为什么我会打印了这么多个呢? 一、第一次尝试——PLATPU 刚开始…...
windows10 获取磁盘类型
powershell Get-PhysicalDisk | Select FriendlyName, MediaType FriendlyName MediaType ------------ --------- NVMe PC SN740 NVMe WD 256GB SSD WDC WD10EZEX-75WN4A1 HDD 适用场景 SSD: 适合需要快速访问速度和较高响…...
数据库之运算符
目录 一、算数运算符 二、比较运算符 1.常用比较运算符 2.实现特殊功能的比较运算符 三、逻辑运算符 1.逻辑与运算符(&&或者AND) 2.逻辑或运算符(||或者OR) 3.逻辑非运算符(!或者NOT&#…...
【自动化机器学习AutoML】AutoML工具和平台的使用
自动化机器学习AutoML:AutoML工具和平台的使用 目录 引言什么是AutoMLAutoML的优势常见的AutoML工具和平台 Google Cloud AutoMLH2O.aiAuto-sklearnTPOTMLBox AutoML的基本使用 Google Cloud AutoML使用示例Auto-sklearn使用示例 AutoML的应用场景结论 引言 自动…...

【每日一练】python求最后一个单词的长度
""" 求某变量中最后一个单词的长度 例如s"Good morning, champ! Youre going to rock this day" 分析思路: 遇到字符串问题,经常和列表结合使用来解决, 可以先用列表的.split()分割方法进行单词分割, 再…...

[红明谷CTF 2021]write_shell 1
目录 代码审计check()$_GET["action"] ?? "" 解题 代码审计 <?php error_reporting(0); highlight_file(__FILE__); function check($input){if(preg_match("/| |_|php|;|~|\\^|\\|eval|{|}/i",$input)){// if(preg_match("/| |_||p…...
【Go - sync.once】
sync.Once 是 Go 语言标准库中的一个结构体,它的作用是确保某个操作在全局范围内只被执行一次。这对于实现单例模式或需要一次性初始化资源的场景非常有用。 典型用法 sync.Once 提供了一个方法 Do(f func()),该方法接收一个没有参数和返回值的函数 f …...

Spark RPC框架详解
文章目录 前言Spark RPC模型概述RpcEndpointRpcEndpointRefRpcEnv 基于Netty的RPC实现NettyRpcEndpointRefNettyRpcEnv消息的发送消息的接收RpcEndpointRef的构造方式直接通过RpcEndpoint构造RpcEndpointRef通过消息发送RpcEndpointRef Endpoint的注册Dispatcher消息的投递消息…...

win10安装ElasticSearch7.x和分词插件
说明: 以下内容整理自网络,格式调整优化,更易阅读,希望能对需要的人有所帮助。 一 安装 Java环境 ElasticSearch使用Java开发的,依赖Java环境,安装 ElasticSearch 7.x 之前,需要先安装jdk-8。…...
Linux中,MySQL的用户管理
MySQL库中的表及其作用 user表 User表是MySQL中最重要的一个权限表,记录允许连接到服务器的帐号信息,里面的权限是全局级的。 db表和host表 db表和host表是MySQL数据中非常重要的权限表。db表中存储了用户对某个数据库的操作权限,决定用户…...
个人电脑网络安全 之 防浏览器和端口溢出攻击 和 权限对系统的重要性
防浏览器和端口溢出攻击 该如何防 很多人都不明白 我相信很多人只知道杀毒软件 却不知道网络防火墙 防火墙分两种 : 1、 病毒防火墙 也就是我们说的杀毒软件 2、 网络防火墙 这是用来防软件恶意通信的 使用防火墙 有两种 1、 半开式规则…...
美食聚焦 -- 仿大众点评项目技术难点总结
1 实现点赞功能显示哪些用户点赞过并安装时间顺序排序 使用sort_set 进行存储,把博客id作为key,用户id作为value,时间戳作为score 但存储成功之后还是没有成功按照时间顺序排名,因为sql语句,比如最后in(5…...

拓扑图:揭示复杂系统背后的结构与逻辑
在现代软件开发和运维中,图形化的表示方式越来越重要。拓扑图,作为一种关键的可视化工具,不仅能够帮助我们理解系统的结构和组件间的关系,还能提升系统的可维护性和可扩展性。 什么是拓扑图? 拓扑图是一种展示系统或网络中各个节点(如服务器、交换机、数据库等)及其连…...

Java面试八股之什么是spring boot starter
什么是spring boot starter Spring Boot Starter是Spring Boot项目中的一个重要概念。它是一种依赖管理机制,用于简化Maven或Gradle配置文件中的依赖项声明。Spring Boot Starter提供了一组预定义的依赖关系,这些依赖关系被封装在一个单一的包中&#x…...
探究项目未能获得ASPICE 1、2级能力的原因及改进策略
项目整体未能获得ASPICE 1、2级能力的原因可能涉及多个方面,以下是基于参考文章中的信息和可能的情境进行的分析: 1.过程成熟度不足:ASPICE(Automotive Software Process Improvement and Capability Determination)是…...
WHAT - 不同 HTTP Methods 使用场景、使用方法和可能遇到的问题
目录 前言基本介绍具体介绍前置知识:幂等和非幂等幂等操作非幂等操作幂等性和非幂等性的应用场景总结 1. GET2. POST3. PUT4. PATCH1. 确保操作是幂等的2. 使用版本控制或条件更新3. 全量更新部分属性4. 使用特定操作指令5. 幂等标识符示例代码总结 5. DELETE6. HEA…...

Pytorch使用教学4-张量的索引
1 张量的符号索引 张量也是有序序列,我们可以根据每个元素在系统内的顺序位置,来找出特定的元素,也就是索引。 1.1 一维张量的索引 一维张量由零维张量构成 一维张量索引与Python中的索引一样是是从左到右,从0开始的ÿ…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...