Skip to content
开发文档
能力中心
应用市场
WebOffice
开发者后台

脚本经典案例

例子1:选中区域快速批量填值

javascript
function main(){
  const time = getNowTime()
  const date = getNowDate()
  ActiveView.Selection(null, ["@日期", "@时间", "@分类"]).Value = [date, time, 'B']
}
// 获取当前时间,格式为 "hh:mm:ss"
function getNowTime() {
  return (new Date()).toTimeString().split(" ")[0]
}
// 获取当前日期,格式为 "yyyy:MM:dd"
function getNowDate() {
  const date = new Date()
  return date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate()
}

main()

例子2:快速实现“一键归档”

下面代码实现了一个文件中两张数据结构相同的表 把表一中的已完成的数据插入到表二中,并删除表一中数据 表结构如下图所示:

例子2

javascript
function main() {
  const criterias = []
  criterias.push(Criteria("@分类",  "Equals", ["B"]))
  criterias.push(Criteria("@完成",  "Equals", ["1"]))
  // 创建filters
  const filters = []
  const filter = {Criterias: criterias, Op: "AND"}
  filters.push(filter)
  const range1 = Sheets(1).Views(1).RecordRange.Condition(filters, "AND")
  if(!range1){
    return
  }
  const length = range1.Count
  const range2 = Sheets(2).Views(1).RecordRange.Add(1, undefined, length)
  range2.Value = range1.Value
  range1.Delete()
}

main()

结合上面两个例子,可以实现自动设置归档日期和时间,或者选中记录一键归档等等功能

例子3:快速删除空白数据

删除名称字段中 值为空的数据

javascript
function deleteRecords() {
  const criterias = []
  criterias.push(Criteria("@名称",  "Equals",['']))
  const filters = []
  const filter = {Criterias: criterias, Op: "AND"}
  filters.push(filter)
  Sheets(3).Views(1).RecordRange.Condition(filters, "AND").Delete()
}
deleteRecords()

例子4:快速创建一张表

javascript
function main() {
  Application.Sheets.Add(
    {
        Type:'xlEtDataBaseSheet',
        Config:{
            fields:
                [
                    {fieldType:'SingleLineText',args:{fieldName:'文本',fieldWidth:15}},
                    {fieldType:'MultiLineText',args:{fieldName:'多行文本',fieldWidth:15}},
                    {fieldType:'Date',args:{fieldName:'日期',numberFormat:'yyyy/mm/dd;@',fieldWidth:15}},
                    {fieldType:'SingleSelect',args:{fieldName:'单选项',fieldWidth:15,listItems:[{value: '选项1', color: 4283466178},{value: '选项2',color: 4281378020}]}},
                    {fieldType:'Number',args:{fieldName:'数字',fieldWidth:15}},
                    {fieldType:'Rating',args:{fieldName:'等级',maxRating:6,fieldWidth:15}},
                ],
            name:'数据表',
            views:
                [
                    {name:'表格视图',type:'Grid'},
                    {name:'表单视图',type:'Form'}
                ]
        }
    })
}
main()

例子5:格式化数据批量插入

javascript
function main(){
    const range = Application.Sheets(4).Views(1).RecordRange.Add(1, undefined, 300)// 在第1行,向上方添加300条记录
    const template = ["商品", 10]
    const range1 = []
    // 给1-300行赋值
    for (let i = 1; i < 301; i++ ) {
        if(i<101){
          range1.push([template[0]+i,template[1],'A'])
        }else if(i<201){
          range1.push([template[0]+i,template[1]+10,'B'])
        }else{
          range1.push([template[0]+i,template[1]+10,'C'])
        }
    }
    range.Value = range1
}
main()

例子 6:自动双向关联

先来看一下表结构

  • 客户表

例子6

  • 拜访记录表

例子6

对 【客户表】 中的"拜访记录" 和 【拜访记录表】 中的 "客户详情"做自动关联

通过客户名称来进行匹配

javascript
function main() {
  const clientsView = Application.Sheets(1).Views(1)
  const clientsCount = clientsView.RecordRange.Count
  
  const visitsView = Application.Sheets(2).Views(1)
  const visitsCount = visitsView.RecordRange.Count

  const clients = clientsView.RecordRange('1:'+clientsCount)
  const visits = visitsView.RecordRange('1:'+visitsCount)

  linkVisits(clients, visits)
  linkClients(clients, visits)
}
// 关联拜访记录表中的客户
function linkClients(clients,visits){
  let name1 = ''
  let name2 = ''
  let id = 0
  // {"value":[{"id":"XP","str":"金山办公"}]}
  for(let i=1;i<visits.Count+1;i++){
    name1 = visits.Item(i,['@客户名称']).Value
    if(name1!==''){
      for(let j=1;j<clients.Count+1;j++){
            name2 = clients.Item(j,['@客户名称']).Value
            id = clients.Item(j).Id
            if(name1 === name2){
              // console.log({id:`${id}`,str:`${name2}`})
              visits.Item(j,['@客户详情']).Value = Application.DBCellValue([id])
              break
            }
      }
    }
    
  }
}
// 关联客户表中的拜访记录
function linkVisits(clients,visits){
  let name1 = ''
  let name2 = ''
  let id = 0
  
  // {"value":[{"id":"XP","str":"金山办公"}]}
  for(let i=1;i<clients.Count+1;i++){
    let vits = []
    name1 = clients.Item(i,['@客户名称']).Value
    if(name1!==''){
      for(let j=1;j<visits.Count+1;j++){
        name2 = visits.Item(j,['@客户名称']).Value
        id = visits.Item(j).Id
        if(name1 === name2){
          vits.push({id:`${id}`,str:`${name2}`})
          // visits.Item(i,['@客户详情']).Value = Application.DBCellValue([{id:`${id}`,str:`${name2}`}])
        }
      }
    }
    // console.log(vits)
    clients.Item(i,['@拜访记录']).Value = Application.DBCellValue(vits)
  }
}

main()

例子7:同步主表数据到其他表

表结构如下

例子7

第一张表中存着所有数据,其他几张表中存着分类数据 当主表中数据更新的时候,期望其他表数据也更新

javascript
// 读取整个表
function getAllRecords(sheetIndex) {
  const view = Application.Sheets(sheetIndex).Views(1)
  const count = view.RecordRange.Count
  return view.RecordRange("1:"+count)
}
// 获取子表中匹配的同步字段数组
function getMatchFields(sheetIndex,toSyncFields){
  const matchFields = []
  const fieldDescs = Application.Sheets(sheetIndex).FieldDescriptors
  for(let i=0;i<toSyncFields.length;i++){
    const fieldName = toSyncFields[i]
    for(let i=1;i<fieldDescs.Count+1;i++){
      if(fieldDescs.Item(i).Name === fieldName){
        matchFields.push('@'+fieldName)
        break
      }
    }
  }
  return matchFields
}
// 检查记录值相同与否, 返回需要更新的记录
function checkFields(mainRecord, record, params) {
  const v1 = mainRecord.Item(1,params).Value
  const v2 = record.Item(1,params).Value
  if(v1===v2) return null
  // console.log(record.Item(1,params).Id,v1)
  return {id:record.Item(1,params).Id[0],val: params.length>1?v1:[v1]}
}

// 同步副表数据
function syncSheet(sheetIndex, mainRecordMap, {
  keyField,
  toSyncFields,
}) {
  const records = getAllRecords(sheetIndex)
  const matchFields = getMatchFields(sheetIndex,toSyncFields)
  // console.log(matchFields)
  const toUpdateIds = []
  const toUpdateVals = []
  for (let i = 1; i < records.Count+1; i++) {
    const record = records.Item(i)
    const name = records.Item(i,['@'+keyField]).Value
    if(name === '') continue
    const mainRecord = mainRecordMap[name]
    if (mainRecord) {
      const updatedResult = checkFields(mainRecord, record, matchFields)
      if (updatedResult) {
        toUpdateIds.push(updatedResult.id)
        toUpdateVals.push(updatedResult.val)
      }
    } else {
      console.error('没有在主表里面找到此条记录: ', name)
    }
  }
  if (toUpdateIds.length > 0) {
    // console.log(toUpdateVals)
    records(toUpdateIds,matchFields).Value = toUpdateVals
  }
}

// 同步主表数据到其他表
function syncMainSheetToOthers(mainSheetName, keyField, toSyncFields) {
  const sheets = Application.Sheet.GetSheets()
  const mainIndex = sheets.findIndex(item => item.name === mainSheetName)+1
  const mainRecords = getAllRecords(mainIndex)
  const recordsMap = {}
  for (let i = 1; i < mainRecords.Count+1; i++) {
    const name = mainRecords.Item(i,'@'+keyField).Value
    if(name === '') continue
    if (recordsMap[name]) {
      console.error('有重复的记录', name)
    }
    recordsMap[name] = mainRecords.Item(i)
  }
  for(let index=1;index<sheets.length+1;index++){
    if(index === mainIndex) continue
    syncSheet(index, recordsMap, {
      keyField,
      toSyncFields,
    })
  }
}

syncMainSheetToOthers('关爱清单', '产品名', ['机制', '价格'])

例子8:获取日期筛选后记录

表结构如下

例子8

使用日期筛选进行获取日期为本月(2023年2月)的记录,即将筛选参数改为thisMonth,如"dynamicType": "thisMonth",筛选得到的记录可查看all变量

javascript
function main(){
  const criterias = []
  criterias.push(Criteria("@日期",  "Equals", [{"dynamicType": "thisMonth","type": "DynamicSimple"}]))
  // 创建filters
  const filters = []
  const filter = {Criterias: criterias, Op: "AND"}
  filters.push(filter)
  const range1 = Application.Sheets(5).Views(1).RecordRange.Condition(filters, "AND")
  console.log(range1.Value)
  return range1
}
main()

例子9:获取联系人筛选后记录

表结构如下

例子9

使用联系人筛选进行获取联系人为Lin的记录,即更改筛选参数value改为“Lin”,如 "values": [ "Lin" ],注意value值为数组形式,筛选得到的记录可查看all变量

javascript
function filterContact() {
    const criterias = [Criteria("@联系人", "Equals", ["WPS_1719228187"])]
    // 创建filters
    const filters = [{Criterias: criterias, Op: "AND"}]
    const all = Application.Sheets(7).Views(1).RecordRange.Condition(filters)
    console.log(all.Value)
    return all
}

filterContact()

例子10:批量将获取的图片url进行文字识别

例子10

  • 可以通过获取的图片url来进行调用百度云文字识别接口,识别图片中的文字

获取所有记录 ,获取该表所有图片URL,调用百度云文字识别接口,识别图片中的文字,并将结果生成在相应记录的“识别文字”字段下。

javascript
const access_token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

function main() {
    const view = Application.ActiveSheet.Views(1)
    const count = view.RecordRange.Count
    // 获取所有记录的图片附件值
    const attachments =  view.RecordRange('1:'+count, ["@图片和附件"]).Value
    // console.log(attachments)
    // 获取对应的url
    const urls = []
    let attachment = []
    // 这里的attachments是一个二维数组
    for(let i=0;i<attachments.length;i++){
        urls[i] = []
        attachment = attachments[i][0].Value
        for(let j = 0;j<attachment.length;j++){
          urls[i].push(attachment[j].LinkUrl || null)
        }
    }
    // console.log(urls)
    let words = []
    let url = []
    for(let i=0;i<urls.length;i++){
      url = urls[i]
      if(url){
        words[i] = [getText(url)]
      }else{
        words[i] = ['']
      }
      // console.log(words[i])
    }
    // console.log(recordIds,words)
    // 赋值到对应的 ‘识别文字’ 这一栏
    view.RecordRange('1:'+count,["@识别文字"]).Value = words
}
// 调用接口把所有的url转换为文字
function getText(urls){
    const word = urls.reduce((word,url)=>{
      // console.log('调用1次')
        let resp = HTTP.fetch('https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token='+access_token,{
                method:"POST",
                timeout:2000,
                headers:{
                  'Content-Type': 'application/x-www-form-urlencoded',
                  'Accept': 'application/json',
                  'Authorization': access_token
            },
                body: `url=${encodeURIComponent(url)}`
            })
        if(resp.status !== 200){
           throw new Error("fetch err! status is "+resp.status)
        }
        return word + resp.text()
    },'')
    return word
}
main()

脚本示例(08/26更新)

javascript
function main(){
  addSheetViewField()
  setDemoValue()
  testRecordRange()
  testFilters()
  testSorts()
  testGroups()
  testGridView()
}
function addSheetViewField(){
    const sheet = Application.Sheets.Add({After:1,Type:"xlEtDataBaseSheet"})
    sheet.Views.Add("Grid",'新建的表格视图')
    addField("MultiLineText","富文本")
    addField("Time","时间")
    addField("Currency","货币")
    addField("Percentage","百分比")
    addField("ID","身份证")
    addField("Phone","电话")
    addField("Email","邮箱")
}
function setDemoValue(){
  setValue("@文本","100")
  setValue("@文本","200",'4:6')
  setValue(2,123)
  setValue(2,456,'4:6')
  setValue(3,"2024/07/13")
  setValue(3,"2024/08/13","4:6")
  setValue("@单选项","选项1")
  setValue("@单选项","选项2","4:6")
  setValue(6,3)
  setValue(6,4,"4:6")
  setValue("@富文本","dfsafdasfdasf")
  setValue("@富文本","fdsfagzgzgfgvcbc","4:6")
  setValue("@时间","8:48:16")
  setValue("@时间","10:48:16","4:6")
  setValue("@货币","123213")
  setValue("@货币","1434434","4:6")
  // setValue(10,1.23)
  // setValue(10,2.35,"4:6")
  setValue("@身份证","43211620050917691X")
  setValue("@身份证","43211620050917691X","4:6")
  setValue("@电话","18064038091")
  setValue("@电话","18064838691","4:6")
  setValue("@邮箱","1437252712@qq.com")
  setValue("@邮箱","1437257777@qq.com","4:6")
}
function addField(type,name,index,valueUnique,defaultValue,defaultValueType,numberFormat,arg1,arg2,arg3,arg4){
    const desc = Application.Sheets(2).FieldDescriptors.FieldDescriptor(type, name)
    if (type === 'SingleSelect' || type === 'MultipleSelect') {
        desc.Items = arg1
    }
    if(type === 'Rating'){
        desc.MaxRating = arg1
    }
    if(type === 'Formula'){
        if (arg1) {
          desc.ValueUnique = arg1
         }if (arg2) {
             desc.ValueType =arg2
         }if (arg3) {
             desc.ShowPercentAsProgress = arg3
         }
    }
    if(type === 'Cascade'){
        const options = Application.CascadeOptions()
         if(typeof arg1 ==='object'){
            const o1 =  options.Add(arg1[0])
            const children = arg1[1]
            for(let i=0;i<children.length;i++){
              o1.Children.Add(children[i])
            }
          }
    if(typeof arg2 ==='object'){
        const o2 =  options.Add(arg2[0])
        const children = arg2[1]
        for(let i=0;i<children.length;i++){
           o2.Children.Add(children[i])
        }
    }
        desc.AllCascadeOption = options
    }
    if (type === 'OneWayLink') {
        desc.LinkSheet = arg1
        desc.IsAutoLink = arg2
    }
    if (valueUnique) {
        desc.ValueUnique = valueUnique
    }
    if (defaultValue) {
        desc.DefaultValue = defaultValue
    }
    if (defaultValueType) {
        desc.DefaultValue = defaultValueType
    }
    if (numberFormat) {
        desc.NumberFormat = numberFormat
    }
    const result =  Application.Sheets(2).FieldDescriptors.AddField(desc, index)
    if(result.Code !== 0){
      console.error(result.Message)
    }
}
function setValue(field,value,index="1:3"){
   if(typeof value === 'object'){
      value = Application.DBCellValue(value)
   }
   Application.Sheets(2).Views(1).RecordRange(index, field).Value = value
   const newVal = Application.Sheets(2).Views(1).RecordRange(index, field).Value
   let setSuccess = true
   if(typeof newVal === 'object'){
     for(let i=0;i<newVal.length;i++){
       if(newVal[i][0] === value){
          setConfirm = false
          break
       }
     }
   }else if(newVal !== value){
     setConfirm = false
   }
   if(!setSuccess)   console.error('setValue异常!')
}
function testRecordRange(){
  // RecordRange: Add、Item、Condition、Delete
  const rr = Application.Sheets(2).Views(1).RecordRange.Add(1,undefined,2)
  rr.Item(1).Value = ["300",789,"2024/09/13","选项1",[],3,"fadfadsf","10:33:33"]
  rr.Item(2).Value = ["400",789,"2024/09/13","选项1",[],3,"fadfadsf","10:33:33"]
  const criterias = [Criteria("@文本", "Equals",['400'])]
  const filters = [{Criterias: criterias, Op: "AND"}]
  const recordRange = Application.Sheets(2).Views(1).RecordRange.Condition(filters)
  if(recordRange){
    recordRange.Delete()
  }
}
function testFilters(){
  //Filters: Add、Item、Clear
  //Filter:  Delete
  Application.Sheets(2).Views(1).Filters.Clear()
  const filters = Application.Sheets(2).Views(1).Filters;
  const criteria = Criteria({
      Field: 1,
      CriteriaOp: 'Equals',
      Values: ["200"]
  })
  const filter = filters.Add(criteria);
  const delResult = filter.Delete()
  if(delResult.Code !== 0) {
    console.error(delResult.Message)
  } 
  const criteria1 = Criteria({
      Field: 1,
      CriteriaOp: 'Equals',
      Values: ["300"]
  })
  Application.Sheets(2).Views(1).Filters.Add(criteria1)
  const clsResult = Application.Sheets(2).Views(1).Filters.Clear()
  if(clsResult.Code !== 0) {
    console.error(clsResult.Message)
  } 
  const criteria2 = Criteria({
      Field: 1,
      CriteriaOp: 'Equals',
      Values: ["100"]
  })
  Application.Sheets(2).Views(1).Filters.Add(criteria2)
  //console.log(Application.Sheets(2).Views(1).Filters.Item(1).Criteria)
}
function testSorts(){
  //Sorts: Add Item Move 
  //Sort:  Delete ChangeField
  const sort= Application.Sheets(2).Views(1).Sorts.Add(2,true)
  if(sort.IsAscending !== true) {
    console.error('Add Sort时 设置IsAscending 异常')
  }
  Application.Sheets(2).Views(2).Sorts.Add(3,false)
  const changeRes = Application.Sheets(2).Views(1).Sorts.Item(1).ChangeField(1)
  if(changeRes.Code !== 0) {
    console.error(changeRes.Message)
  }
  Application.Sheets(2).Views(1).Sorts.Move([3,1])
  Application.Sheets(2).Views(1).Sorts.Add(2,false)
  const delRes = Application.Sheets(2).Views(1).Sorts.Item(2).Delete()
  if(delRes.Code !== 0) {
    console.error(delRes.Message)
  }
}
function testGroups(){
  // Groups: Add FoldAll UnFoldAll Item StatisticResult
  // Group:  ChangeField Delete
  const group = Application.Sheets(2).Views(1).Groups.Add(1,true)
  if(group.IsAscending !== true) {
    console.error('groups add 方法设置IsAscending 异常')
  }
  Application.Sheets(2).Views(1).Groups.Add(2,false)
  Application.Sheets(2).Views(1).Groups.FoldAll()
  const changeResult = Application.Sheets(2).Views(1).Groups.Item(2).ChangeField(3)
  if(changeResult.Code !== 0) {
    console.error(changeResult.Message)
  } 
  Application.Sheets(2).Views(1).Groups.Add(2)
  const delResult = Application.Sheets(2).Views(1).Groups.Item(2).Delete()
  if(delResult.Code !== 0) {
    console.error(delResult.Message)
  } 
  // console.log(Application.Sheets(2).Views(1).Groups.StatisticResult(1))
  Application.Sheets(2).Views(1).Groups.UnFoldAll()
}
function testGridView(){
    const gridView = Application.Sheets(2).Views.Add('Grid', '表格视图');
    if(!gridView.RowHeight){
       console.error('Views.Add表格视图时,返回值异常')
    }
    const itemGridView = Application.Sheets(2).Views(1)
    if(!itemGridView.RowHeight){
        console.error('Views.Item获取表格视图时,返回值异常')
    }
    const activeGridView = Application.ActiveView
    if(!activeGridView.RowHeight){
        console.error('ActiveView获取表格视图时,返回值异常')
    }
    Application.ActiveView.RowHeight = 'Medium';
    if(Application.ActiveView.RowHeight !== 'Medium'){
        console.error('设置GridView的RowHeight结果时异常')
    }
}
main()

更多API用法可参考多维表API

回到旧版