Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Excel附件、Outlook或Gmail中的数据传输到Google工作表_Excel_Vba_Google Apps Script_Google Sheets_Outlook - Fatal编程技术网

将Excel附件、Outlook或Gmail中的数据传输到Google工作表

将Excel附件、Outlook或Gmail中的数据传输到Google工作表,excel,vba,google-apps-script,google-sheets,outlook,Excel,Vba,Google Apps Script,Google Sheets,Outlook,我每天都会在Outlook中收到一封电子邮件,并附上Excel表格 我正在使用Google data studio中的仪表板/模板以及Google工作表。为了使这项工作顺利进行,我需要将数据从Excel工作表自动传输到我的Google工作表。这可能吗 我的第一个想法是将附加的Excel表格发送到我的gmail,因为从这里我可以编写一个脚本,从gmail获取数据。这比我想象的要复杂 可能需要一个VBA代码将附加的Excel文件传输到google drive,然后从那里我可以更新我的google工作

我每天都会在Outlook中收到一封电子邮件,并附上Excel表格

我正在使用Google data studio中的仪表板/模板以及Google工作表。为了使这项工作顺利进行,我需要将数据从Excel工作表自动传输到我的Google工作表。这可能吗

我的第一个想法是将附加的Excel表格发送到我的gmail,因为从这里我可以编写一个脚本,从gmail获取数据。这比我想象的要复杂

可能需要一个VBA代码将附加的Excel文件传输到google drive,然后从那里我可以更新我的google工作表?这可能吗


注意:我没有足够的经验从头开始编写VBA/APP脚本。

Q:OP询问:是否可以将作为Outlook附件接收的Excel电子表格传输到google drive,然后将其更新为google工作表格式

A:是。
Q:满足OP目标所需的离散步骤是什么?
A:
1-在Outlook中编写宏,自动将电子邮件和Excel附件转发到OP的GMail帐户;特别是用于登录Google Sheets的帐户。为了回答这个问题,这方面虽然相当简单,但被视为离题

2-在Google Drive中创建一个文件夹(或文件夹/子文件夹),用于保存Excel电子表格。这可以手动完成,也可以通过脚本完成。“手动”更简单,“按脚本”更有趣,更灵活

3-运行Google脚本访问OP的Gmail帐户,识别Excel附件(例如,以“xls”、“xlsx”、“xlsm”结尾的文件-可以添加其他变体),并将Excel文件保存到Google Drive文件夹。在每封相关电子邮件上贴上“标签”,以便只处理新的未处理邮件

4-运行Google脚本访问Google Drive文件夹/子文件夹,并将Excel电子表格转换为Google工作表。
正如评论中所指出的,这个话题以前曾以这样或那样的形式多次被提出:这是两个很好的例子。谷歌搜索将揭示许多其他主题-关于StackOverflow和其他来源

然而,谷歌服务(文档、脚本、API等)正在不断增强。这一发展的副产品之一是,某些方法已停止使用,这可能导致以前正确的答案过时

不幸的是,2018年1月的答案中提供的出色的
GmailToDrive()
函数就是这种情况。谷歌的高级硬盘服务和硬盘API在2018年发生了变化,这一出色的答案现在已经到了最后一关

提供以下代码是为了提供2019年2月的更新。 这个答案的基础是Rebot先生提供的
GmailToDrive()
函数,但针对Excel文件进行了修改


触发器

该代码应设置为时间驱动、可安装的触发器。频率因情况而异。OP可以做出自己的评估。还有其他来源可以解释这一点


驱动器API

OP必须激活驱动器API(高级服务以及谷歌云平台API仪表板)。为清楚起见,本答案末尾简要概述了这些步骤


代码

// GLOBALS
// Array of file extension which you would like to extract to Drive
var fileTypesToExtract = ['xls', 'xlsx', 'xlsm'];

//Name of the folders in google drive in which files will be put
var homeFolder = "009-StackExchange"; // a folder branching from the root
var ExcelFolderName = "010-GmailToDrive"; // sub folder of "homeFolder"

//Name of the label which will be applied after processing the mail message
var emaillabelName = 'GmailToDrive';

function so54755021()
// an adaptation of function GmailToDrive()
{

  //build query to search emails
  var query = '';

  // loop through the filestoextract and add to query
  for (var i in fileTypesToExtract) {
    query += (query == '' ? ('filename:' + fileTypesToExtract[i]) : (' OR filename:' + fileTypesToExtract[i]));
  }
  //Logger.log("DEBUG: #01 the query is: " + query); //DEBUG

  query = 'in:inbox has:nouserlabels ' + query;
  //Logger.log("DEBUG: #02 the query is: " + query); //DEBUG

  var threads = GmailApp.search(query);
  //Logger.log("DEBUG: threads = " + threads + "; threads length = " + threads.length); //DEBUG

  var label = getGmailLabel_(emaillabelName);
  //Logger.log("DEBUG: label = " + label); //DEBUG (GmailToDrive)

  var parentFolder;

  if (threads.length > 0) {
    //Logger.log("DEBUG: threads length is more than zero");//DEBUG

    //Logger.log("DEBUG: folder name = " + folderName); //DEBUG  
    //parentFolder = getFolder_(folderName); // subroutine

    // build sub-folder if necessary
    createDriveFolder(homeFolder, ExcelFolderName);
    parentFolder = homeFolder;

  }


  for (var i in threads) {
    var mesgs = threads[i].getMessages();
    for (var j in mesgs) {
      //get attachments
      var attachments = mesgs[j].getAttachments();
      for (var k in attachments) {
        var attachment = attachments[k];
        //Logger.log("DEBUG: attachment: " + attachment);//DEBUG

        var isExcelType = checkIfExcel_(attachment);
        //Logger.log("DEBUG: isExceltype = " + isExcelType);//DEBUG

        if (!isExcelType) continue;

        // Copy the Blob
        var attachmentBlob = attachment.copyBlob();
        //Logger.log("DEBUG: attachmentblob = " + attachmentBlob);//DEBUG

        var ExcelFolderObject = DriveApp.getFoldersByName(ExcelFolderName).next();

        //Create the Excel file in Google Drive
        var file = ExcelFolderObject.createFile(attachmentBlob);

        // get the file name and ID
        var fileid = file.getId();
        var filename = file.getName();
        // Logger.log("DEBUG: file = " + file + ", and ID = " + fileid + ", and file name: " + filename);//DEBUG
        var fileType = file.getMimeType()
        // Logger.log("DEBUG: the MIME type is " + fileType);//DEBUG

        // copy the Blob again in preparation for conversion
        var xBlob = file.getBlob();

        // get the folder ID to copy the file
        var folderId = DriveApp.getFoldersByName(ExcelFolderName).next().getId();

        // set parameters for the new file
        var newFile = {
          title: filename + '_converted',
          key: fileid,
          parents: [{
            "id": folderId
          }]

        }

        // convert the file
        var convfile = Drive.Files.insert(newFile, xBlob, {
          convert: true
        });
        // Logger.log("DEBUG: the converted file is " + convfile);//DEBUG

      }
    }

    // Add the label to the Gmail item
    threads[i].addLabel(label);
  }
}


// If necessary, create the label in GMail
function getGmailLabel_(name) {
  var label = GmailApp.getUserLabelByName(name);
  if (label == null) {
    label = GmailApp.createLabel(name);
  }
  return label;
}

function createDriveFolder(baseFolder, folderName) {

  var baseFolderObject = DriveApp.getFoldersByName(baseFolder).next();
  //Logger.log("DEBUG: basefolderobject = " + baseFolderObject);//DEBUG
  var folders = DriveApp.getFoldersByName(baseFolder).next().getFolders();
  //Logger.log("DEBUG: folders: "+folders);//DEBUG

  // set variable to detect a match
  var foldermatch = 0;

  //Loop through folders
  while (folders.hasNext()) {

    var folder = folders.next();
    //Logger.log(DEBUG: folder.getName());//DEBUG

    // If the folder name matches
    if (folder.getName() == folderName) {

      // update the match variable
      foldermatch = 1;
      // Logger.log("DEBUG: there's a match/folder exists: " + folder.getName());//DEBUG
    }
  }

  // Do something is there is a match
  if (foldermatch != 0) {
    //Logger.log("DEBUG: There was a match so do NOTHING");//DEBUG


  } else {
    // Logger.log("DEBUG: There was no match so create the folder"); //DEBUG
    baseFolderObject.createFolder(folderName);
  }

  // The folder already existed, or it has been created. Either way, our work is done.
  return;
}


// this function will check for filextension type.
// and return boolean
function checkIfExcel_(attachment) {
  var fileName = attachment.getName();
  var temp = fileName.split('.');
  var fileExtension = temp[temp.length - 1].toLowerCase();
  if (fileTypesToExtract.indexOf(fileExtension) != -1) return true;
  else return false;
}

启用驱动器Api

1-从脚本编辑器中,选择资源>高级谷歌服务;选择驱动器API并将开关滑到On位置。


2-点击“谷歌云平台API仪表板”链接


3-谷歌云平台-API和服务屏幕将在新窗口中打开。
单击链接以启用API和服务


4-搜索“驱动器”,然后单击驱动器API选项。


5-单击驱动器API的“启用”按钮


6-系统将显示驱动器API详细信息;注意:驱动器API已启用。那就把窗户关上。


7-点击“谷歌服务进展”屏幕上的OK(该屏幕一直处于打开状态)。
您已准备好运行脚本。

您如何识别此电子邮件?它有特定的主题吗?是某个特定的发件人寄来的吗?我假设google驱动器与Windows程序中的任何其他驱动器一样。如果一个谷歌硬盘看起来确实像其他硬盘,那么你可以将附件保存到它。我怀疑最简单的方法是指定一个规则来识别电子邮件,然后附加一个脚本来保存附件。事实上,这并不像看上去那么难,尽管作为一个新手,我承认这会给珠穆朗玛峰带来挑战——我们可以提供帮助。但一般来说,这个主题以前已经讨论过了:您是否能够编写宏,将Outlook邮件项目连同Excel附件“自动”转发到您的GMail帐户?如果没有,那么这是你应该调查的事情。正如@TonyDallimore所提到的,Outlook邮件(来源、标题、发件人、收件人等)可能有一些与众不同的地方,这将使您能够将范围缩小到仅限于特定的电子邮件。非常感谢!!你真好!我会研究这些建议。