0

我想使用 excel office 脚本将一列拆分为行,但我不知道如何。

我在 excel 中有一个以下格式的时间表,我想将其分成几列。

原表

决赛桌需要这样。

决赛桌

这可以实现吗,如果可以,有人可以分享代码吗

4

1 回答 1

0

根据您的描述,我尝试使用 Office 脚本解决方案。它需要一个这样的表:

一周中的活动表

并在新工作表上输出一个新表,如下所示:

活动日期表

无论好坏,我试图通过从第一个表派生的公式将逻辑保留在工作簿中并输出到第二个表中。如果每天有多个活动,则需要重写此公式逻辑。

我不是开发人员,但我已经可以看到此 Office 脚本中需要改进的地方:

function main(workbook: ExcelScript.Workbook) {
  // delete new worksheet if it already exists so the rest of the script can run effectively
  // should you need to retain data simply rename worksheet before running
  if (workbook.getWorksheet("My New Sheet") != undefined) {
    workbook.getWorksheet("My New Sheet").delete()
  }
  // assumes your original data is in a table
  let myTable = workbook.getTable("Table1");
  let tableData = myTable.getRangeBetweenHeaderAndTotal().getValues();
  
  // extract the dates as excel serial numbers
  let allDates:number[] = [];
  for (let i = 0; i < tableData.length; i++) {
    allDates.push(tableData[i][2], tableData[i][3]);
  }
  let oldestDate = Math.min(...allDates);
  let newestDate = Math.max(...allDates);
  let calendarSpread = newestDate-oldestDate+2;

  // construct formula from the tableData
  // first add a new 'column' to tableData to represent the days of the week (as numbers) on which the activity is planned. this will be an array added to each 'row'.
  for (let r = 0; r < tableData.length; r++) {
    tableData[r].push(findDay(tableData[r][1]));
  }
  // start a near blank formula string
  let formulaText:string = '=';
  // use the following cell reference
  let cellRef = 'C2';
  // construct the formual for each row in the data and with each day of the week for the row
  let rowCount:number;
  for (let r = 0; r < tableData.length; r++) {
    if (tableData[r][4].length > 1) {
      formulaText += 'IF(AND(OR(';
    } else {
      formulaText += 'IF(AND(';
    }
    for (let a=0; a < tableData[r][4].length; a++) {
      formulaText += 'WEEKDAY(' + cellRef + ')=' + tableData[r][4][a].toString();
      if (a == tableData[r][4].length - 1 && tableData[r][4].length > 1) {
        formulaText += '),';
      } else {
        formulaText += ', ';
      }
    }
    formulaText += cellRef + '>=' + tableData[r][2] + ', ' + cellRef + '<=' + tableData[r][3] + '), "' + tableData[r][0] + '", ';
    rowCount = r+1;
  }
  formulaText += '"-"';
  for (let p=0; p<rowCount; p++) {
    formulaText += ')';
  }

  // create a new sheet
  let newSheet = workbook.addWorksheet("My New Sheet");
  // add the header row
  let header = newSheet.getRange("A1:C1").setValues([["Activity", "Day", "Date"]])
  // insert the oldest date into the first row, then add formula to adjacent cells in row
  let firstDate = newSheet.getRange("C2")
  firstDate.setValue(oldestDate);
  firstDate.setNumberFormatLocal("m/d/yyyy");
  firstDate.getOffsetRange(0, -1).setFormula("=C2");
  firstDate.getOffsetRange(0, -1).setNumberFormatLocal("ddd");
  firstDate.getOffsetRange(0, -2).setFormula(formulaText);
  // use autofill to copy results down until the last day in the sequence
  let autoFillRange = "A2:C" + (calendarSpread).toString();
  firstDate.getResizedRange(0, -2).autoFill(autoFillRange, ExcelScript.AutoFillType.fillDefault);
  // convert the the range to a table and format the columns
  let outputTable = newSheet.addTable(newSheet.getUsedRange(), true);
  outputTable.getRange().getFormat().autofitColumns();
  //navigate to the new sheet
  newSheet.activate();
}

// function to return days (as a number) for each day of week found in a string 
function findDay(foo: string) {
  // start with a list of days to search for
  let daysOfWeek:string[] = ["Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"];
  //create empty arrays
  let searchResults:number[] = [];
  let daysFound:number[] = [];
  // search for each day of the week, this will create an array for each day of the week where the value is -1 if the day is not found or write the position where the day is found
  for (let d of daysOfWeek) {
    searchResults.push(foo.search(d));
  }
  // now take the search results array and if the number contained is greater than -1 add it's position+1 to a days found array. this should end up being a list of numbered days of the week found in a string/cell
  for (let i = 0; i < searchResults.length; i++) {
    if (searchResults[i] > -1) {
      daysFound.push(i + 1);
    }
  }
  return daysFound
}
于 2021-11-30T23:27:39.303 回答