我不确定它是否仍然相关,但是您需要ACE字符串“ WP”。这允许相关的身份(在SID字符串中提到)开始/停止服务。因此,如果您想让管理员停止和启动的能力,则需要使用以下内容(“ BA” SID字符串代表内置管理员,也可以添加管理员帐户的SID)
D:(A;;CCLCSWRPLOCRRCWDWP;;;BA)
:您写道:
D:P(A;;CCLCSWRPLOCRRCWD;;;SY)(A;;CCLCSWLOCRRCWD;;;SU)(A;;CCLCSWRPLOCRRCWDWP;;;BA)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
似乎您还没有诚实地尝试。来自文档它是在顶部写的:
// Obtain shared preferences.
final prefs = await SharedPreferences.getInstance();
// Save an String value to 'action' key.
await prefs.setString('action', 'Start');
// Try reading data from the 'action' key. If it doesn't exist, returns null.
final String? action = prefs.getString('action');
我不明白的一件事是,您正在使用vlookup(...,...,1,...)
:据我了解vlookup()
用于以下情况:
a b c
1 10 100
2 20 200
3 30 300
...您想在'c'列中找到值,与“ a”列中的值2相对应。在这种情况下,您正在寻找值2,并且在第三列中查看,例如vlookup(...,...,3,...)
。
但是,如果您只是在寻找该值本身,而不是使用vlookup(lookup_value,range,1,extcret_match)
,您可以使用match> match(lookup_value,range,range,extcret_match)。
下班后,这是完全没有证件的解决方案。
三个(或两个)1x图像:
- 应为400.240(实际上,如果大小错了,就不会引起任何问题)
三个(或两个)2x图像:
- 必须严格严格为800.480 ,或者会遇到灾难性的失败。在4K型号上
令人沮丧的是,资产文件夹中的某些图像包括工作和正确的警报,例如:
但是,实际的“应用程序图标”插槽没有任何工作警报。
底线,必须正好是800.480。
“顶架”图像是:
1920.720和3840.1440
“顶架宽”图像是:
2320.720和4640.1440
您的应用程序是业务类型吗?第三点提到“创建一个元应用:转到开发人员。Facebook.com>我的应用程序>创建应用程序。选择“业务”类型,然后在屏幕上关注提示”。
(我简要查看C程序的构建块,然后检查通常隐藏在GCC调用后面的构建步骤。)
传统的编译语言,例如C和C ++,在通常是源文件中组织了一个一个一个,“编译”到一个“对象文件”中。每个源文件都是一个“翻译单元” - 在处理了所有包含指令之后。 (因此,翻译单元通常由一个以上的文件组成,相同的包含文件通常发生在一个以上的翻译单元中 - 文件和翻译单元严格说是N:M关系。但是,务实地可以说一个人可以说一个“翻译单元”是一个c文件。)
要将单个源文件编译到对象文件中,一个人将-c
flag传递给编译器:
gcc -c myfile.c
这将在同一目录中创建myfile.o
,或者也许myfile.obj
。
对象文件包含机器代码和数据(以及潜在的调试信息,但我们在这里忽略了它)。机器代码包含函数,数据以变量的形式出现。对象文件中的函数和变量都具有称为“符号”的名称。编译器通常通过准备下划线或类似程序,在C ++中转换程序中的变量和函数名称,生成的(“ mangled”)名称包含有关类型和函数的信息。
某些符号,例如全局变量和正常函数的名称,可从其他对象文件中使用;他们被“出口”。
只需简化的符号就可以将其视为地址别名:对于功能,该名称是跳跃目标地址的别名;对于变量,名称是程序可以读取的内存位置的地址和可以编写的记忆位置的一个别名。
您的文件帮助。C包含函数herp
的代码。 C中的功能默认情况下具有“外部链接”,可以从其他翻译单元中使用它们。他们的名字 - “符号” - 被导出。
在Modern C中,源文件使用 在不同的翻译单元中定义的名称必须声明该名称。这告诉编译器如何处理它,以及在源代码中可以在哪种方式上使用句法(例如,调用函数,分配到变量,索引一个数组)。编译器会产生从此“符号地址”中读取的代码,或跳到该“符号地址”;链接器的作业是将所有这些符号地址替换为“真实”内存位置,这些位置指向最终可执行文件中的现有数据和代码,以便跳跃和内存访问已降落在所需的位置。
文件中的名称(函数,变量)的声明是使用的声明,它可以是“手动”,例如void herp();
,在您的文件中直接出现在您的文件中首先使用。不过,更通常,在翻译单元中定义的名称可以使用其他翻译单元,在标题文件中声明了您的helper.h
。使用翻译单元使用#include
-ing it在标题文件中使用的“罐头”声明。这里没有魔术。一个包含指令只需插入包含的文件文本,就好像它直接写在文件中一样。差异恰好为零。特别是,包括标头文件不会告诉链接器与相应的源文件链接。原因很简单:链接器永远不会知道随附的文件,因为在编译过程中删除了该知识进入对象文件。
这意味着在您的情况下,必须汇总help.c
,并且必须告诉链接器与程序的其余部分结合(“链接”),在您的情况下,汇编中的代码main.c
讨论如何完成工作更加困难,因为此过程非常普遍,以至于典型的C编译器集成了编译和链接阶段:gcc -o myprog help.c main.c main.c main.c main.c
简单地做所有必要的事情创建一个可执行的myProg
。
当我们说“编译器”时,例如参考gcc
,我们通常是指从命令行中获取命令和文件的“编译器驱动程序”,并执行必要的步骤以实现所需的结果,例如从我们的来源生产可执行程序。 GCC的实际编译器是cc1
,它会生成一个必须将 as “组装”到对象文件中的汇编文件。编译源文件后,GCC使用适当的选项调用链接器,从而产生可执行文件。
这是一个示例会话详细介绍阶段:
$ ls
Makefile help.c help.h main.c
$ /lib/gcc/x86_64-pc-cygwin/7.4.0/cc1 main.c
main
Analyzing compilation unit
Performing interprocedural optimizations
<*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-inline-summary> <emutls> <whole-program> <inline>Assembling functions:
<materialize-all-clones> <simdclone> main
Execution times (seconds)
phase setup : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 (22%) wall 1184 kB (86%) ggc
TOTAL : 0.00 0.00 0.01 1374 kB
$ ls
Makefile help.c help.h main.c main.s
$ /lib/gcc/x86_64-pc-cygwin/7.4.0/cc1 help.c
herp
Analyzing compilation unit
Performing interprocedural optimizations
<*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-inline-summary> <emutls> <whole-program> <inline>Assembling functions:
<materialize-all-clones> <simdclone> herp
Execution times (seconds)
phase setup : 0.01 (100%) usr 0.00 ( 0%) sys 0.00 (33%) wall 1184 kB (86%) ggc
TOTAL : 0.01 0.00 0.01 1370 kB
$ ls
Makefile help.c help.h help.s main.c main.s
我们现在有两个汇编文件,main.s and help.s,可以将它们与汇编程序一起组装到对象文件中。但是,让我们快速查看help.s
:
$ cat help.s
.file "help.c"
.text
.globl some_variable
.data
.align 4
some_variable:
.long 1
.text
.globl herp
.def herp; .scl 2; .type 32; .endef
.seh_proc herp
herp:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
.seh_endprologue
nop
popq %rbp
ret
.seh_endproc
.ident "GCC: (GNU) 7.4.0"
即使我们对汇编器一无所知,我们也可以清楚地识别符号some_variable
和herp
,是组装标签。
忘记了我添加了一个可变定义以帮助
$ cat help.c
#include "help.h"
int some_variable = 1;
void herp() {}
。
$ as main.s -o main.o
$ ls
Makefile help.c help.h help.s main.c main.o main.s
$ as help.s -o help.o
$ ls
Makefile help.c help.h help.o help.s main.c main.o main.s
啊,是的,我 我们可以看到哪些符号被导出(“ extern”)或所需的(“未定义”),该实用程序 nm
(“ n ame m 钓鱼”):
$ nm --extern-only help.o
0000000000000000 T herp
0000000000000000 D some_variable
$ nm --extern-only main.o
U __main
U herp
“ t”表示符号在“文本”部分中,其中包含代码; “ D”是数据部分,“ U”代表“未定义”。 (未定义的__ main
是 gcc和/或cygwin quirk 。)
在这里您有问题的源头:除非您将main.o与定义的对象文件配对未定义的符号,链接器无法“解析”名称并不能产生跳跃。没有跳跃目的地。
现在,我们可以将两个对象文件链接到可执行文件。 cygwin要求我们与cygwin.dll链接;对不起。
$ ld main.o help.o /bin/cygwin1.dll -o main
$ ls
Makefile help.c help.h help.o help.s main* main.c main.o main.s
就是这样。我应该补充说,该程序无法正常运行。它没有结束,也不会对CTRL-C反应;我可能缺少一些GNU或Windows建立了GCC为我们做的错综复杂。
啊,makefiles。 makefiles由这些目标的 target 定义和依赖关系:一行
main:help.o main.o
指定目标“ main”两个.o文件。
MakeFiles通常还包含规则指定如何产生目标。但是制造有内置的规则;它知道您调用编译器从.c文件中生成.o文件(并且它会自动考虑此依赖关系),并且知道您将O文件链接在一起以根据目标链接到目标,前提是目标与.o文件之一相同。
因此,我们不需要任何规则:我们简单地定义了非依赖依赖性。您项目的整个makefile归结为:
$ cat Makefile
CC=gcc
main: help.o main.o
help.o: help.h
main.o: help.h
cc = gcc
指定要使用的C编译器。 CC是指定C编译器的内置变量(CXX将指定C ++编译器,例如G ++)。
让我们看看:
$ make
gcc -c -o main.o main.c
gcc -c -o help.o help.c
gcc main.o help.o -o main
$ ls
Makefile help.c help.h help.o main.c main.exe* main.o
依赖关系有效吗?
$ make
make: 'main' is up to date.
$ touch main.c
$ make
gcc -c -o main.o main.c
gcc main.o help.o -o main
$ touch help.h
$ make
gcc -c -o main.o main.c
gcc -c -o help.o help.c
gcc main.o help.o -o main
看起来不错:触摸单个源文件后,只需编译该文件;但是,触摸两个文件依赖的标头使得两者都使得两者兼而有之。无论如何,链接都需要完成。
我在Boost Asio中的握手也有一些挑战。我在Filemaker插件中使用它,当涉及到这一行时:
namespace net = boost::asio;
..
..
stream.handshake(net::ssl::stream_base::handshake_type::client, ec);
因此,它崩溃了整个应用程序。
经过数小时,更改设置,谷歌搜索并阅读文档后,我将该方法放入了一个小的独立应用程序中,就像在孤立的环境中对其进行测试一样。在插件代码和测试应用程序中都具有所有相同的Boost版本(1.82.0)和相同的OpenSSL库(3.1.4)。
在测试应用程序中,它可以按预期工作。代码从服务器检索数据。在具有相同代码的插件中,FileMaker崩溃。
在您的下方,您可以查看崩溃日志片段以及测试应用程序的代码。
崩溃日志
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 FileMaker Pro Advanced 0x10a6f7b64 boost::system::error_category::equivalent(boost::system::error_code const&, int) const + 4
1 ACF_plugin_db 0x116ce2f4d boost::system::detail::failed_impl(int, boost::system::error_category const&) + 93 (error_category.hpp:217)
2 ACF_plugin_db 0x116ce2ea5 boost::system::error_code::error_code(int, boost::system::error_category const&) + 53 (error_code.hpp:129)
3 ACF_plugin_db 0x116ce2dd3 boost::system::error_code::error_code(int, boost::system::error_category const&) + 35 (error_code.hpp:130)
4 ACF_plugin_db 0x116d0ee6d boost::asio::error::make_error_code(boost::asio::error::misc_errors) + 45 (error.hpp:354)
5 ACF_plugin_db 0x116d11acf boost::system::error_code::error_code<boost::asio::error::misc_errors>(boost::asio::error::misc_errors, boost::system::detail::enable_if<(is_error_code_enum<boost::asio::error::misc_errors>::value) || (std::is_error_code_enum<boost::asio::error::misc_errors>::value), void>::type*) + 63 (error_code.hpp:150)
6 ACF_plugin_db 0x116d11a83 boost::system::error_code::error_code<boost::asio::error::misc_errors>(boost::asio::error::misc_errors, boost::system::detail::enable_if<(is_error_code_enum<boost::asio::error::misc_errors>::value) || (std::is_error_code_enum<boost::asio::error::misc_errors>::value), void>::type*) + 35 (error_code.hpp:149)
7 ACF_plugin_db 0x116d10612 boost::asio::ssl::detail::engine::map_error_code(boost::system::error_code&) const + 50 (engine.ipp:240)
8 ACF_plugin_db 0x116d1024f unsigned long boost::asio::ssl::detail::io<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::ssl::detail::handshake_op>(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>&, boost::asio::ssl::detail::stream_core&, boost::asio::ssl::detail::handshake_op const&, boost::system::error_code&) + 607 (io.hpp:81)
9 ACF_plugin_db 0x116d0ffbc boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor> >::handshake(boost::asio::ssl::stream_base::handshake_type, boost::system::error_code&) + 76 (stream.hpp:437)
10 ACF_plugin_db 0x116cdf364 boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor> >::handshake(boost::asio::ssl::stream_base::handshake_type) + 52 (stream.hpp:420)
11 ACF_plugin_db 0x116cde1de SendSoapRequest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 1710 (DocServiceXML.cpp:256)
测试应用程序的工作来源与插件相同的代码
//
// main.cpp
// test-boost-ssl
//
// Created by Ole Kristian Ek Hornnes on 02/11/2023.
//
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
namespace net = boost::asio;
namespace ssl = boost::asio::ssl;
namespace http = boost::beast::http;
using tcp = boost::asio::ip::tcp;
struct httpResponse {
int StatusCode;
std::string ResultText;
};
httpResponse SendPostRequest(const std::string& xurl, const std::string& post_data) {
net::io_context ioc;
std::string url = xurl;
// Determine the scheme (http or https), hostname, and path
std::string scheme, hostname, path;
int port = 0;
httpResponse httpResult;
if (url.substr(0, 5) == "https") {
scheme = "https";
port = 443;
url = url.substr(8); // Remove "https://"
} else if (url.substr(0, 4) == "http") {
scheme = "http";
port = 80;
url = url.substr(7); // Remove "http://"
}
size_t slashPos = url.find('/');
if (slashPos != std::string::npos) {
hostname = url.substr(0, slashPos);
path = url.substr(slashPos);
} else {
hostname = url;
path = "/";
}
bool useSSL = (scheme == "https");
// These objects perform I/O
try {
if ( useSSL ) {
// Set up SSL context and stream
// Set up SSL context (only if using SSL)
net::io_context xxx;
tcp::resolver resolver(xxx);
// tcp::socket socket(ioc);
net::ssl::context sslContext(net::ssl::context::tlsv12_client);
// sslContext.set_options(net::ssl::context::default_workarounds);
/* sslContext.set_options(net::ssl::context::no_sslv2);
sslContext.set_options(net::ssl::context::no_sslv3);
sslContext.set_options(net::ssl::context::tlsv12);*/
sslContext.set_default_verify_paths();
net::ssl::stream<tcp::socket> stream = {xxx, sslContext };
// Resolve the hostname and port
auto it = resolver.resolve(hostname, std::to_string(port));
// std::cout << "resolver " << std::string(it) << std::endl;
boost::system::error_code ec;
net::connect(stream.next_layer(), it, ec);
if (ec) {
std::stringstream err;
err << "Error during SSL connect: " << ec << std::endl;
httpResult.ResultText = err.str();
httpResult.StatusCode = -2;
return httpResult;
}
// stream.set_verify_mode(net::ssl::verify_peer);
// Perform the SSL handshake
try {
stream.handshake(net::ssl::stream_base::handshake_type::client, ec);
} catch (const std::exception &e) {
std::stringstream err;
err << "Error during SSL handshake: " << e.what() << "ec: " << ec << std::endl;
httpResult.ResultText = err.str();
httpResult.StatusCode = -2;
return httpResult;
}
if (ec) {
std::stringstream err;
err << "Error during SSL Handshake: " << ec << std::endl;
httpResult.ResultText = err.str();
httpResult.StatusCode = -3;
return httpResult;
}
std::string agent ("ACF_Plugin for FileMaker ver. ");
// agent += std::string (PLUGIN_VERSION);
// Set up an HTTPS POST request
http::request<http::string_body> req{http::verb::post, path, 11};
req.set(http::field::host, hostname);
req.set(http::field::user_agent, agent);
req.set(http::field::content_type, "text/xml");
// req.set(http::field::soapaction, SoapAction);
req.body() = post_data;
req.prepare_payload();
// Send the HTTP request
http::write(stream, req);
// This buffer is used for reading and must be persisted
boost::beast::flat_buffer buffer;
// Declare a container to hold the response
http::response<http::string_body> res;
// Receive the HTTP response
http::read(stream, buffer, res);
// Convert the response to a std::string and return it
// Check the HTTP status code and set StatusCode accordingly
httpResult.StatusCode = static_cast<int>(res.result_int());
httpResult.ResultText = res.body();
return httpResult;
} else {
tcp::socket socket(ioc);
tcp::resolver resolver(ioc);
// Resolve the hostname and port
auto results = resolver.resolve(hostname, std::to_string(port));
boost::asio::connect(socket, results.begin(), results.end());
// Set up an HTTP POST request
http::request<http::string_body> req{http::verb::post, path, 11};
req.set(http::field::host, hostname);
req.set(http::field::user_agent, "MyClient/1.0");
req.set(http::field::content_type, "text/xml");
/* if (SoapAction != "" ) {
req.set(http::field::soapaction, SoapAction);
} */
req.body() = post_data;
req.prepare_payload();
// Send the HTTP request
http::write(socket, req);
// This buffer is used for reading and must be persisted
boost::beast::flat_buffer buffer;
// Declare a container to hold the response
http::response<http::string_body> res;
// Receive the HTTP response
http::read(socket, buffer, res);
// Convert the response to a std::string and return it
// Check the HTTP status code and set StatusCode accordingly
httpResult.StatusCode = static_cast<int>(res.result_int());
httpResult.ResultText = res.body();
return httpResult;
}
} catch (const std::exception &e) {
std::stringstream err;
err << "Error: " << e.what() << std::endl;
httpResult.ResultText = err.str();
httpResult.StatusCode = -1;
return httpResult;
}
}
int main(int argc, char* argv[]) {
std::string url;
if (argc != 2) {
// std::cerr << "Usage: postService <URL>" << std::endl;
// return 1;
url = "https://myserver.no/wsx/doc/";
} else {
url = argv[1];
}
std::string post_data = "TEST\n\n"; // You can set your POST data here
httpResponse result = SendPostRequest(url, post_data);
std::cout << "URL: " << url << std::endl;
std::cout << "HTTP Status Code: " << result.StatusCode << std::endl;
std::cout << "Response Body:\n" << result.ResultText << std::endl;
return 0;
}
在显示通信的测试时示例输出,我得到了肥皂失误,但是由于我没有't实际上发送了任何有效的肥皂请求,预期。但是,它表明功能与服务器交换数据。
URL: https://myserver.no/ws/doc/
HTTP Status Code: 500
Response Body:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Bad Request</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
Program ended with exit code: 0
您需要跟踪此处的最小数据将是用户最新操作和当前条纹计数的日期。
当用户执行条纹操作时,您需要检查最新操作的日期。如果最近的动作发生在不到一天之内,但现在已经是不同的一天,那么您就会增加条纹计数。如果超过两天,您将条纹计数重置为零;否则,您在检查条纹时会更新最新的动作时间戳
,则需要检查最新的动作时间戳。如果时间戳是最后一天的最后更新,则条纹数量是有效的,否则实际条纹计数确实为零。
另外,您只需简单地执行文档数据库,然后根据事务日志进行完整的条纹计算。对于长条纹用户来说,这将变得昂贵,尽管这将是最简单的实施。取决于您期望人们长期条纹的频率,这可能是可以接受的,也可能是不可接受的。
尝试这样
DELETE FROM
MyTable
WHERE
Name like '%NULL%' OR
Name like '%Null%' OR
Name like '%null%'
当Python解释器导入软件包时,它在以下位置寻找包:
包含输入脚本(或当前目录)的目录。
pythonpath(目录名称的列表,具有与Shell变量路径相同的语法)。
依赖安装的默认值。
因此,如果您的软件包和脚本文件位于同一目录中,将很容易找到。但是显然您选择了另一个目录。然后,您必须使用文章中提到的方法来指定解释器的路径,例如修改 pythonpath 环境变量或使用sys.path.append()
方法。
这是另一种方法的建议。将您的软件包放在Python可以找到它的位置,例如lib
文件夹。这样,您就不需要在每个文件开头使用sys.path.append()
方法。
我正在使用虚拟环境
更新:
您可以使用虚拟环境。它不会有所作为。如果您担心某些因素并且不想使用它,那就没有问题了。只需在当前环境中找到lib
文件夹,然后将包装放入其中即可。
例如(就我的计算机而言):
lib
与此环境解释器相对应的文件夹在:
C:\Users\Admin\AppData\Local\Programs\Python\Python310\Lib
lib
与此环境解释器相对应的文件夹在:
C:\Users\Admin\anaconda3\Lib
ps:也可以放置在site-packages 文件夹在
lib
文件夹下方的一个级别。
您可以使用match()
,或find()
。这是一个使用match()
的示例
Sub Import_QTN_Data()
Dim FileToOpen As Variant
Dim OpenBook As Workbook, wsQuote As Worksheet, m
Application.ScreenUpdating = False
FileToOpen = Application.GetOpenFilename( _
Title:="Browse for your File & Import Range", _
FileFilter:="Excel Files (*.xls*),*xls*")
If FileToOpen <> False Then
Set wsQuote = ThisWorkbook.Worksheets("QUOTATION")
Set OpenBook = Application.Workbooks.Open(FileToOpen)
With OpenBook.Worksheets("QUOTATION")
'use Match() on ColD
m = Application.Match(.Range("T2").Value, wsQuote.Columns("D"), 0)
If Not IsError(m) Then 'got a match (`m` is not an error value)
.Range("U2:AH2").Copy
wsQuote.Cells(m, "E").PasteSpecial xlPasteValues, skipblanks:=True
End If
End With
OpenBook.Close False
End If
Application.ScreenUpdating = True
End Sub
您可以使用此修改后的正则:
(?<=await)([\S\s]*?)(?<!.+\.lean\(\))(;)
我所更改的只是:
负面外观。
制作\。精益
逃脱括号背后的
在典型的编译器实现中,您可以将代码视为“用Adress打印出 的代码”。另外,如果您将新功能调用添加到构成本地int
的函数中,则很有可能a
的值用来指向)更改。发生这种情况是因为堆栈将被包含不同数据的新帧覆盖。
但是,这是不确定的行为,您不应依靠它来工作!
尝试一下。将Excel Workbook放入SharePoint之后,请从SharePoint内部打开工作簿,然后选择编辑下拉列表, 在桌面应用程序中打开:
然后,在工作簿中,单击 file &gt; info &gt; 复制路径。 (这将为您提供电源查询所需的路径才能直接检索工作簿。如果您尝试使用SharePoint的功能复制路径的路径,这与您所获得的路径不同。)
粘贴该路径以安全地使用。然后关闭您的工作簿并打开电源查询。
在电源查询中,创建两个新参数:
单击 home &gt; 管理参数的底部按钮&gt; 新参数:
将名称从 parameter1 更改为路径并将类型更改为 text ,然后将您复制的工作簿复制的路径粘贴到当前值 box 。然后,从刚粘贴的路径中删除了最后一个前向斜线(/)之后的所有文本。确保您做< / strong>将最后 /包含在路径中。您将在单独的参数中放置以下内容的文件名,并且不需要?web = 1 < / em>。
不要单击确定。,请单击 new ,在管理参数窗口的顶部。这将设置您创建文件名参数。
将名称从 parameter1 更改为 fileName ,然后将 type 更改为 text ,然后粘贴您复制的文件名工作簿进入当前值框。同样,您不需要原始路径中的?web = 1 。
单击确定。
现在,您可以在源行中使用参数,路径和文件名。这是这样做的方法:
这将为您提供这样的表:
------------------------------------------------------------------------ -
对于Mirza的后续操作,关于从SharePoint文件夹中提取文件,请尝试以下操作:
连接。
您的 root 在SharePoint中使用文件夹,然后单击“确定”。
想打开。 (使用顶端的下拉箭头。)
文件可以存储在多个文件夹中,您需要确保
您正在通过与正确的文件匹配正确的文件
文件夹,这为此设定了阶段。)
您应该以这样的代码结束(yourdomain.sharepoint.com/your/root/folder/url将是您的 root root 在SharePoint中的文件夹):
您应该看到类似的东西此:
在内容列中单击二进制文件。
------------------------------------------------------------------------ -
对于Mirza的第二次随访,关于从SharePoint文件夹中摘取多个文件而不是仅一个文件,请尝试以下操作:
连接。
在SharePoint中使用文件的root文件夹,然后单击“确定”。你可能有
输入您的凭据。如果是这样,请这样做。
粘贴您刚刚从文件夹路径列复制到的路径
路径参数的当前值:
单击“家”,然后单击“管理参数”,然后,如果您尚未创建路径参数,请单击新(否则单击路径参数以选择它):
单击“ .sstatic.net/vggHt.png" rel="nofollow noreferrer">
确保您的路径参数如下:
然后,在过滤行的公式框中,更改
路径(包括引号)到路径。也就是说,更改此信息:
= table.selectrows(源,每个([folder path] =“ https://yourdomain.sharepoint.com/sites/testteam/shared documents /shared documents/enter/general/”))
to ...
= table.selectrows(源,每个(([folder path] = path)))
您应该能够用任何其他有效根文件夹中的文件夹路径。
由于这些源文件位于SharePoint内,因此SharePoint的访问控件占上风。因此,要使用户能够访问实际的源文件,这是刷新需要做的,需要刷新的用户将需要适当的SharePoint访问权限的源文件以访问它们。但是,我可以肯定的是,一旦完成了刷新,任何可以访问您的文件的用户(无论是在Excel还是Power BI文件中)都应该能够看到其结果,而没有他们的结果需要对基础源文件的SharePoint访问权限。我的理解是,只有那些实际访问源文件(例如刷新)的人才需要访问这些文件的人。无论如何,这是我的经验。
Try this. After you have placed your excel workbook into SharePoint, open the workbook from within SharePoint and then select the Editing dropdown and Open in Desktop App:
Then, in the workbook, click File > Info > Copy Path. (This will get you the path you need for power query to directly retrieve the workbook. It is different than what you would have gotten if you tried to copy the path using SharePoint's features for copying the path.)
Paste that path somewhere safe for reuse. Then close your workbook and open Power Query.
In Power Query, create two new parameters:
Click Home > the bottom part of the Manage Parameters button > New Parameters:
Change the name from Parameter1 to path and change the Type to Text, then paste the path you copied for your workbook into the Current Value box. Then, from the path you just pasted, delete all the text that follows the last forward slash (/). Make sure you do include that last / in the path. You'll put the file name that follows the / in a separate parameter and won't need the ?web=1.
Don't click OK. Instead, click New, at the top of the Manage Parameters window. This will set you up to create the filename parameter.
Change the name from Parameter1 to filename and change the Type to Text, then paste the filename you copied for your workbook into the Current Value box. Again, you won't need the ?web=1 from the original path.
Click OK.
Now you can use the parameters, path and filename in your source line. And here's how to do that:
This will give you a table like this:
-------------------------------------------------
For Mirza's follow-up, regarding pulling the files from the SharePoint folder, try this instead:
Connect.
your root folder for your files in SharePoint and click OK.
want to open. (Use the dropdown arrow at the top-right.)
files can be stored in multiple folders and you'll want to be sure
you are selecting the right file by matching it with its correct
folder, and this sets the stage for that.)
You should wind up with code like this (yourdomain.sharepoint.com/your/root/folder/URL would be your URL to your root folder for your documents in sharepoint instead):
You should see something like this:
Click Binary, in the Content column.
-------------------------------------------------
For Mirza's second follow-up, regarding pulling multiple files from the SharePoint folder instead of just one file, try this instead:
Connect.
root folder for your files in SharePoint and click OK. You may have
to enter your credentials. If so, do that.
To paste the path you just copied from the Folder Path column to the
path parameter's current value:
Click Home, then click on Manage Parameters, then if you haven't already created the path parameter, click new (otherwise click on the path parameter to select it):
Make sure your path parameter is set up like this:
Then, in the formula box for the Filtered Rows, change the name of
the path (including the quotes) to path. That is, change this:
= Table.SelectRows(Source, each ([Folder Path] = "https://yourdomain.sharepoint.com/sites/TestTeam/Shared Documents/General/"))
to...
= Table.SelectRows(Source, each (([Folder Path] = path)))
You should be able to replace the current value of the path parameter with any other valid folder path within your root folder.
Since these source files reside within SharePoint, SharePoint's access controls prevail. So, for a user to be able to access the actual source files, which is what a refresh needs to do, the users who need to refresh will need appropriate SharePoint access rights to the source files in order to access them. However, I'm fairly certain that once the refresh has been done, any users who have access to your file that is built from this query's results (be it in an excel or Power BI file) should be able to see its results without them needing SharePoint access rights to the underlying source files. My understanding is that only those people who actually access to the source files, like for refresh, require the SharePoint access to those files. This has been my experience anyway.
如何为来自SharePoint的文件创建动态文件路径,以查询power查询?