SAP GUI Scripting - 如何判断组件是否存在
总体来说,SAP Scripting 与 BDC 类似,因为是屏幕录制,就可能碰到不同的情况,比如每个录入的数据不同,可能出现一个对话框,或者出现一个状态栏消息。这种任何有变化的情况,在 Scripting 中没有考虑到,就会导致操作失败。本文以导入 MR21 物料价格为例,演示如何处理组件/控件不存在的情况。
基于连续性,如何使用 SAP SAP Scripting 的要点,请参考本人之前的博文:
SAP Scripting Tracker基本使用技巧-CSDN博客
SAP Scripting Tracker基本使用技巧(续)_sap tracker-CSDN博客
SAP Scripting Tracker基本使用技巧 - VBA 示例-CSDN博客
首先使用 SAP Scripting Tracker 基于 Basic 录制 MR21 修改物料价格,得到下面的代码:
session.findById("wnd[0]").resizeWorkingPane(116, 39, vbFalse)
session.findById("wnd[0]/tbar[0]/okcd").text = "MR21"
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/ctxtMR21HEAD-BUDAT").text = "2024.12.31"
session.findById("wnd[0]/usr/ctxtMR21HEAD-BUKRS").text = "3600"
session.findById("wnd[0]/usr/ctxtMR21HEAD-WERKS").text = "3601"
session.findById("wnd[0]/usr/txtMR21HEAD-XBLNR").setFocus
session.findById("wnd[0]/usr/txtMR21HEAD-XBLNR").caretPosition = 0
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]").text = "20000239"
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]").caretPosition = 8
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").text = "100"
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").setFocus
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").caretPosition = 3
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").setFocus
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").caretPosition = 4
session.findById("wnd[0]/tbar[0]/btn[11]").press
录制过程中,为方便后续对代码的理解,可以在关键点插入空行,或插入空行并加上注释。因为最终需要从 Excel 的单元格导入数据,所以接下来对代码进行微调,将写死的部分替换为单元格。我一般先定义一个起始的单元格,然后其他单元格都替换为基于起始单元格的 offset:
Dim leftCell As Range
Set leftCell = Sheet1.Range("A" & i)session.findById("wnd[0]").resizeWorkingPane(116, 39, vbFalse)
session.findById("wnd[0]/tbar[0]/okcd").text = "MR21"
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/ctxtMR21HEAD-BUDAT").text = leftCell.Offset(0, 2).Value ' 过账日期
session.findById("wnd[0]/usr/ctxtMR21HEAD-BUKRS").text = leftCell.Value ' 公司代码
session.findById("wnd[0]/usr/ctxtMR21HEAD-WERKS").text = leftCell.Offset(0, 1).Value ' 工厂
session.findById("wnd[0]/usr/txtMR21HEAD-XBLNR").setFocus
session.findById("wnd[0]/usr/txtMR21HEAD-XBLNR").caretPosition = 0
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]").text = leftCell.Offset(0, 3).Value ' 物料编码
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]").caretPosition = 8
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").text = leftCell.Offset(0, 4).Value '新价格
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").setFocus
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").caretPosition = 3
session.findById("wnd[0]").sendVKey(0)session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").setFocus
session.findById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").caretPosition = 4
session.findById("wnd[0]/tbar[0]/btn[11]").press
正常情况下,这个脚本就可以用了。本来 MR21 是一个表格式界面,可以处理多条记录,但 Scripting 是通过位置索引来表达某个单元格,因为项目物料不是很多,所以采取简单的方式,每一条记录保存之后再录入下一个物料,就解决了这个问题。
但物料本身的数据存在差异,录入的时候会碰到不同的情况,比如有些物料本身已经有将来或当前的价格,有些物料在修改的时候,如果新价格等于老价格,SAP就会在状态栏有一个提示:对于XXX物料,价格没有变化。对这种的情况,如果不处理,VBA 会抛出异常,所以需要处理。
我们先来讲怎样通过 Scripting Tracker 查看这个控件。在查看之前,需要制造出抛出异常的情景。
然后刷新 Scripting Tracker,显示控件的 ID:
有了这个 ID 之后,我们可以通过两个方法来处理,推荐的是第二个方法。
方法1
Dim msg As String
On Error Resume Next
msg = session.FindById("/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1") '价格没有修改对话框
If Err.Number = 0 ThenleftCell.Offset(0, 5).Value = session.FindById("/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1").Text
End If
方法2
第二个参数为 False。
Public Function FindById( _ByVal Id As String, _Optional ByVal Raise As Variant _
) As GuiComponent
在对象的子对象中搜索给定的 ID。如果参数是完全限定的 ID,函数将首先检查容器对象的 ID 是否是 ID 参数的前缀。如果是这种情况,这个前缀将被截断。如果找不到具有给定 ID 的后代,除非将可选参数 raise 设置为 False,否则函数将引发异常。(Search through the object’s descendants for a given id. If the parameter is a fully qualified id, the function will first check if the container object’s id is a prefix of the id parameter. If that is the case, this prefix is truncated. If no descendant with the given id can be found the function raises an exception unless the optional parameter raise is set to False.)
API 可以参考:GuiContainer Object | SAP Help Portal
If Not session.FindById("/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1", False) Is Nothing Then '价格没有修改对话框leftCell.Offset(0, 5).Value = session.FindById("/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1").Text
Else' 读取返回值leftCell.Offset(0, 5).Value = session.FindById("wnd[0]/sbar").Text
End If
最后给出 Excel 界面和完整的代码。
SapSesion.bas
Option ExplicitPublic Function GetSession() As ObjectDim SapGuiAuto As ObjectDim app As SAPFEWSELib.GuiApplicationDim connection As SAPFEWSELib.GuiConnectionDim session As SAPFEWSELib.GuiSessionIf app Is Nothing ThenSet SapGuiAuto = GetObject("SAPGUI")Set app = SapGuiAuto.GetScriptingEngineEnd IfIf connection Is Nothing ThenSet connection = app.Children(0)End IfIf session Is Nothing ThenSet session = connection.Children(0)End IfSet GetSession = session
End FunctionPublic Sub returnEasyAccess(sess As Object)sess.FindById("wnd[0]/tbar[0]/okcd").Text = "/n"sess.FindById("wnd[0]").SendVKey (0)
End Sub'Public Sub test()
' Dim s As Object
' Set s = GetSession
'
' returnEasyAccess s
'End Sub
DataImport.bas
Option ExplicitPublic Sub DataImport()Dim session As ObjectSet session = GetSession' 确认If Not msgbox("脚本将对当前打开的SAP系统进行更改物料价格更改,请不要随意点击执行。是否继续?", vbYesNo + vbExclamation) = vbYes ThenExit SubEnd IfDim pwd As Stringpwd = InputBox("请输入密码")If pwd = "" ThenExit SubEnd IfIf pwd <> "stonestone" Thenmsgbox "密码不正确"Exit SubEnd IfCall returnEasyAccess(session)'==================================' 执行'==================================Dim i As LongFor i = 4 To Sheet1.UsedRange.CountIf Sheet1.Range("A" & i).Value = "EOF" Then Exit Sub' 每次先回到Easy Access 界面Call returnEasyAccess(session)Dim leftCell As RangeSet leftCell = Sheet1.Range("A" & i)session.FindById("wnd[0]").Maximize' 功能代码'=======================================================================session.FindById("wnd[0]/tbar[0]/okcd").Text = "MR21"session.FindById("wnd[0]").SendVKey (0)session.FindById("wnd[0]/usr/ctxtMR21HEAD-BUDAT").Text = leftCell.Offset(0, 2).Value ' 过账日期session.FindById("wnd[0]/usr/ctxtMR21HEAD-BUKRS").Text = "3600" ' 公司代码session.FindById("wnd[0]/usr/ctxtMR21HEAD-WERKS").Text = leftCell.Offset(0, 1).Value ' plantsession.FindById("wnd[0]/usr/ctxtMR21HEAD-WERKS").SetFocussession.FindById("wnd[0]/usr/ctxtMR21HEAD-WERKS").CaretPosition = 4session.FindById("wnd[0]").SendVKey (0)session.FindById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]").Text = leftCell.Offset(0, 3).Value ' 物料编码session.FindById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]").CaretPosition = 8session.FindById("wnd[0]").SendVKey (0)'如果物料有将来价格则存在对话框If Not session.FindById("wnd[1]/tbar[0]/btn[0]", False) Is Nothing Thensession.FindById("wnd[1]/tbar[0]/btn[0]").PressEnd Ifsession.FindById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").Text = leftCell.Offset(0, 4).Value '新价格session.FindById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").SetFocussession.FindById("wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]").CaretPosition = 4session.FindById("wnd[0]").SendVKey (0)' Savesession.FindById("wnd[0]/tbar[0]/btn[11]").Press' Save之后可能提示物料价格没有更改If Left(session.FindById("wnd[0]/sbar").Text, 4) = "对于物料" Thensession.FindById("wnd[0]").SendVKey (0)End If'====================================================================If Not session.FindById("/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1", False) Is Nothing Then '价格没有修改对话框leftCell.Offset(0, 5).Value = session.FindById("/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1").TextElse' 读取返回值leftCell.Offset(0, 5).Value = session.FindById("wnd[0]/sbar").TextEnd If' 保存If i Mod 5 = 0 ThenThisWorkbook.SaveEnd If' 滚动If i >= 25 ThenActiveWindow.SmallScroll down:=1End IfNext
End Sub
相关文章:

SAP GUI Scripting - 如何判断组件是否存在
总体来说,SAP Scripting 与 BDC 类似,因为是屏幕录制,就可能碰到不同的情况,比如每个录入的数据不同,可能出现一个对话框,或者出现一个状态栏消息。这种任何有变化的情况,在 Scripting 中没有考…...
Go 计算Utf8字符串的长度 不要超过mysql字段的最大长度
背景: 我有一个mysql的字段,是utf8格式的,但有时候前端传的字符串会超长,为此我需要在后端接口,先判断是否超长,如果超长,则报错提示前端。 代码: // 计算utf8下,字符串…...

llamafactory报错:双卡4090GPU,训练qwen2.5:7B、14B时报错GPU显存不足(out of memory),轻松搞定~~~
实际问题场景: 使用llamafactory进行微调qwen2.5 7B和14B的大模型时,会出现out of memory的报错。尝试使用降低batch_size(原本是2,现在降到1)的方式,可以让qwen2.5:7B跑起来,但时不时会不稳定…...
全局webSocket 单个页面进行监听并移除单页面监听
之前全局封装的 webSocket 在某些特定的页面中使用会直接去调用 webSocket 的 onMessage 方法 已进入页面就会调,如果退出页面移除整个监听的话全局监听就会被移除 这是修改后的 全局封装 let token uni.getStorageSync(token) const HEARTBEAT_INTERVAL 1 *…...

JVM调优实践篇
理论篇 1多功能养鱼塘-JVM内存 大鱼塘O(可分配内存): JVM可以调度使用的总的内存数,这个数量受操作系统进程寻址范围、系统虚拟内存总数、系统物理内存总数、其他系统运行所占用的内存资源等因素的制约。 小池塘A&a…...

【JavaEE】Spring Web MVC
目录 一、Spring Web MVC简介 1.1 MVC简介1.2 Spring MVC1.3 RequestMapping注解1.3.1 使用1.3.2 RequestMapping的请求设置 1.3.2.1 方法11.3.2.2 方法2 二、Postman介绍 2.1 创建请求2.2 界面如下:2.3 传参介绍 一、Spring Web MVC简介 官方文档介绍ÿ…...
VSCode 插件开发实战(七):插件支持了哪些事件,以及如何利用和监听这些事件
前言 VSCode 作为现代开发者的首选编辑器之一,其核心优势在于其高度可扩展性。通过自定义插件,开发者可以根据自己的需求对编辑器进行功能扩展和优化。在这些插件开发过程中,事件处理和监听机制尤为重要,它们允许插件在特定事件发…...

指针详解之 多层嵌套的关系
1 例子之指向3个字符串的指针数组,易混淆! 1.1过程详解: char *str[3]{ "Hello,thisisasample!", "Hi,goodmorning.", "Helloworld" }; char s[80]; strcpy(s,str[0]); //也可写成strcpy(s,*st…...

Animated Drawings:让纸上的角色动起来
前言 今天介绍的这个工具非常的有意思:它可以让我们在纸上绘画的角色动起来。先一起来看看效果: 准备 首先,我们先准备一张绘画。可以在纸上进行绘制,也可以在电子设备上进行绘制。绘制内容不限,在这里为了方便演示&am…...

技术与教育的结合:高校听课评价系统的设计与实施
3.1系统可行性分析 需要使用大部分精力开发的高校听课评价系统为了充分降低开发风险,特意在开发之前进行可行性分析这个验证系统开发是否可行的步骤。本文就会从技术角度,经济角度,还有用户使用的程序的运行角度进行综合阐述。 3.1.1 技术可行…...
web移动端项目常用解决方案
移动端总会遇到一系列特定于移动设备的问题,分享下常见的移动端常见问题的处理方案。 1px边框问题 在高清屏幕下,1px的边框显示得比较粗。 .border-1px {position: relative; } .border-1px::after {position: absolute;content: ;width: 200%;height:…...

LabVIEW软件项目设计方案如何制定
制定LabVIEW软件项目设计方案需要综合考虑需求分析、架构设计、功能模块划分和时间预算等多个方面,确保项目开发过程高效、可控且最终满足目标要求。以下是一个详细的制定流程: 1. 需求分析 目标定义:明确项目的目标,例如数据采…...

数据结构(Java)——链表
1.概念及结构 链表是一种 物理存储结构上非连续 存储结构,数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。 2.分类 链表的结构非常多样,以下情况组合起来就有 8 种链表结构: (1)单向或者双向 (…...
变量与数据类型 - 整型、浮点型、字符型等
引言 在编程中,变量和数据类型是基础中的基础。理解它们如何工作以及如何正确使用它们对于编写高效且无误的代码至关重要。本文将详细介绍 C 中的几种基本数据类型:整型、浮点型、字符型等,并通过实例帮助读者更好地理解和掌握这些概念。 一…...

MacOS安装Xcode(非App Store)
文章目录 访问官网资源页面 访问官网资源页面 直接访问官网的历史版本下载资源页面地址:https://developer.apple.com/download/more/完成APP ID的登陆,直接找到需要的软件下载即可 解压后,安装将xcode.app移动到应用程序文件夹。...

运行Zr.Admin项目(后端)
1.下载Zr.Admin代码压缩包 https://codeload.github.com/izhaorui/Zr.Admin.NET/zip/refs/heads/main 2.打开项目 我这里装的是VS2022社区版 进入根目录,双击ZRAdmin.sln打开项目 3.安装.net7运行时 我当时下载的代码版本是.net7的 点击安装 点击安装࿰…...

Ubuntu24.04最新版本安装详细教程
Ubuntu 24.04 LTS发布说明 推荐的系统配置要求: 双核2 GHz处理器或更高 4 GB系统内存 25 GB磁盘存储空间 可访问的互联网 光驱或USB安装介质 Ubuntu 24.04官方下载网址:https://cn.ubuntu.com/download/desktop 04. Ubuntu 22.04(创建虚拟机方式一) 4…...
js版本之ES6特性简述【Proxy、Reflect、Iterator、Generator】(五)
目录 Proxy Reflect 静态方法 部分实例 Iterator 实际开发迭代器的使用实例 迭代器(Iterator)应用 Generator Proxy Proxy 是 ES6 中新增的对象 Proxy 是JavaScript中的内置对象,它提供了一种机制,可以拦截并自定义各种…...
CSS实现一个自定义的滚动条
要使用CSS创建一个自定义的滚动条,你可以使用伪元素和CSS的伪类来控制滚动条的外观和行为。以下是一个简单的例子,展示如何为任何HTML元素添加一个自定义的滚动条样式: <!DOCTYPE html> <html lang"en"> <head> …...

CKA认证 | Day8 K8s安全
第八章 Kubernetes安全 1、Kubernetes RBAC授权 Kubernetes 基于角色的访问控制(Role-Based Access Control, RBAC) 是一种强大的权限管理机制,用于控制用户、用户组、服务账户对 Kubernetes 集群资源的访问。通过 RBAC,可以细…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...