自定义函数 JSAFETCH3 在单元格中返回请求响应的异步数据

function JSAFETCH3(url, init) { // 名称法
    url = url.valueOf();
    init = (init === undefined || init === -2147352572) ? undefined : JSON.parse(init.valueOf());
    
    let rng = Application.Caller();
    let ws = rng.Worksheet;
    let wb = ws.Parent;
    let wbFullName = wb.FullName;
    
    let nameKey = 
        "asyncResult_" + // 开头加 (asyncResult_)
        Run("JSA_A_STRINGTOBASE64STRING", `'${wb.Path}\\[${wb.Name}]${ws.Name}'!${rng.Address()}`) // 转base64
        .replace( // (+ / =) 替换为 (加 除 等)
            /[+/=]/g, 
            v => {
                let obj = Object.fromEntries([["+", "加"], ["/", "除"], ["=", "等"]]);
                return obj[v];
            }
        );
    //console.log(nameKey);
    
    if (nameKey > 255) {
        return "名称命名不能超过255个字符。";
    }
    
    let resultName;
    
    try {
        resultName = wb.Names(nameKey);
    } catch (err) {
        resultName = null;
    }
    
    if (resultName) {
        let result = resultName.Value.replace(/^=/g, '') // 去除开头添加的 (=) 号
            .slice(1, -1) // 去除首尾添加的 (") 号
            .slice(1) // 去除开头添加的 (半角空格) 号
            .replace(/""/g, '"'); // 还原 ("") 号 为 (") 号
        //console.log(result);
        
        try {
            //wb.Names(nameKey).Delete();
            resultName.Delete(); // 删除名称
        } catch (err) { // 如果删除名称失败,添加到字典。
            nameDelete_obj[nameKey] = wbFullName;
        }
        
        return result;
    }
    
    function addNameDirtyCalculate(text) {
        wb.Names.Add(nameKey, " " + text); // 开头添加1个半角空格
        
        let earliestTime = new Date(Date.now() + 1000).toLocaleTimeString();
        Application.OnTime(earliestTime, "nameDelete"); // 预定"定时任务"
        
        rng.Dirty(); // 标记为脏单元格。
        
        if (Application.Calculation == xlCalculationManual) { // 自动重算:xlCalculationAutomatic、手动重算:xlCalculationManual
            rng.Calculate(); // 手动重算模式,需设置此项,相当于手动进入单元格按Enter或按F9。自动重算模式,不需要设置此项。
        }
    }
    
    return (async () => {
        let response = await fetch(url, init);
        
        if (!response.ok) {
            const statusAndStatusText = `HTTP ${response.status}: ${response.statusText}`;
            addNameDirtyCalculate(statusAndStatusText);
            return statusAndStatusText;
        }
        
        const text = await response.text();
        addNameDirtyCalculate(text);
        return text;
    })();
}

var nameDelete_obj = {};
function nameDelete() {
    if (Object.keys(nameDelete_obj).length > 0) {
        for(let [nameKey, wbFullName] of Object.entries(nameDelete_obj)) {
            let wb = Workbooks(wbFullName);
            
            try {
                wb.Names(nameKey).Delete();
            } catch (err) {
                
            }
            
            delete nameDelete_obj[nameKey];
        }
    }
}

插入函数对话框、函数参数对话框:

加载宏文件function Workbook_Open(){}中添加以下代码。

Application.MacroOptions("JSAFETCH3","发起获取资源的请求,返回一个会在请求响应后兑现的promise。该promise会兑现一个表示请求响应的Response对象。",undefined,undefined,undefined,undefined,14,undefined,undefined,undefined,["想要获取的资源的URL。","一个可选对象的JSON格式,包含希望被包括到请求中的各种自定义选项。"])

云南省
浏览 204
2
3
分享
3 +1
2 +1
全部评论