邮件合并与从Excel或SQL数据库分组键字段

我已经search了互联网find一个解决scheme,但到目前为止,没有成功。 我有VBA和SQL中的中级技能,但一直无法创build我所需要的。

我有一个数据库与以下信息。

Co.Name |Email | Product | Q | SH1 |info@sh.com | Orange | 105.566 | SH1 |info@sh.com | Berries | 200.000 | BT1 |info@bt.com | Orange | 300.000 | BT4 |info@bt.com | Apple | 101.700 | WT1 |info@wt.com | Berries | 201.040 | WT6 |info@wt.com | Apple | 204.000 | 

Co.Name是指Company_Name,Q是数量。

我需要一个邮件合并插入一个独占表使用键字段来形成表。

在之前的虚拟表中,关键字段可以是公司名称或公司邮件。

 **Email** To: <emailcompany1> Subject: Enquiry of <productname1>, <productname2>, ..., <productnamei> Dear sirs from <company_name1> In name of StackOverflow Inc, I'm requesting a price quotation and availability of the following products so we can feed this huge and awesome online community: !-- Here it has to insert an specific table for the company name !-- so it only shows the information regarding that company.! Table<CompanyName1> | Product | Q | | Product 1 | Q. Prod 1 | | Product 2 | Q. Prod 2 | | Product ... | Q. Prod ...| | Product i | Q. Prod i | Regards StackOverflow Supply Manager <end mail, and repeat for other company, until there are no more companies..> 

我试图用Word邮件合并到Outlook,并使用Excel数据表与一个小的虚拟数据库。 我发现这个https://support.microsoft.com/en-us/kb/294686 ,但我不能设法做它想要做的事情。

编辑:我已经部分成功与https://support.microsoft.com/en-us/kb/294686 。 目前,我有格式化表的问题。 如果我把桌子放在2×2上,并有4个产品,它就停止工作。

我有一个大型的数据库,其数据点和variables不尽相同,需要很多电子邮件。 我需要一个可以处理这个负载的系统。

澄清:我需要邮件合并,插入一个关键字**的特定表(在虚拟情况下,关键字段是他们company_name或company_email)。

我很stream利的SQL查询,并使用Microsoft SQL Server,但我还没有能够在Excel中解决它,所以我不想使用SQL连接。 数据库目前使用SQL,并且可以访问SQL,Excel,Access,Google应用程序(办公室中的Gmail)等。

如果有一个支付scheme,或一些macros观的,我可以跟我的老板说,看看我们能不能买。 一切都比手动发送电子邮件更快。

在尝试了不同的方法(公司的Fmtp服务器,谷歌脚本,macros)之后,我决定把它放在我的联盟之外,我通过freelancer.com聘请了一位专家。

程序员做了一个VBA代码,在一张纸上使用excel文件作为数据库,第二张纸用作电子邮件的模板。

然后它与outlook连接并发送消息。 表格通过HTML在Outlook上插入。

我们遇到的最困难的部分是在LOGO上添加签名,但是我们使用VBA上的GetBoiler函数一起解决了这个问题:

 Function GetBoiler(ByVal sFile As String) As String 'Dick Kusleika Dim fso As Object Dim ts As Object Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2) GetBoiler = ts.ReadAll ts.Close End Function Signature SigString = Environ("appdata") & "\Microsoft\Signatures\test_mailing.htm 'change_text_mailing.htm with correct path If Dir(SigString) <> "" Then Signature = GetBoiler(SigString) Else Signature = "" End If 

最后,制作这个程序花了我100美元,这是完全可以成本的,我每天发了1.000多封邮件,没有任何问题。

这个方法唯一的小问题就是GMAIL不能正确地读取HTML代码,所以当把邮件发送给在GMAIL上打开的人时,表格显示不好,没有格式,尽pipe在MS Outlook,Hotmail,Yahoo ,表的格式是好的

为了解决这个问题,我们决定,在电子邮件中,它也是与.xlsx上的附件相同的表格。

我知道我没有给出完整的答案,但是这花费了我一些钱和空闲时间的许多工作。 完整的答案包括VBAmacros5.000 +行和用户forms的大型程序,它不只是一个简单的代码,我想它会。

我正在写这个说,这是可能的使用Excel和Outlook的VBA做到这一点。 正如我所做的那样。

如果您愿意按照您的post标签所build议的方式在Google Apps脚本中创build此代码,则可以使用下面的代码。 该代码将使用Google表格中的信息从模板创build个性化的项目。 这将需要将您的数据库移动到Google环境中,并且如果您尚未学习,请使用一些基本的JavaScript。

这些代码是我为自己的用途而编写的,它使用Google表单进行数据收集,一个带有两个名为“Check”和“URL”的额外栏的Google表单,一个HTML模板以及一个准备好的Google Doc模板。 我将讨论可能与您的邮政编码有关的修改。

 function mergeApplication() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName("Sheet Where Form Data is Processed"); var formSheet = ss.getSheetByName("Form Responses"); var lastRow = formSheet.getLastRow(); var lastColumn = sheet.getMaxColumns(); function checkAndComplete() { var urlColumn = lastColumn; //Provides a direct link to the file created var checkColumn = (urlColumn - 1); var checkRange = sheet.getRange(2, checkColumn, (lastRow - 1), 1); var check = checkRange.getBackgrounds(); //This shows status of the code var red = "#ff0404"; var yellow = "#ffec0a"; var green = "#3bec3b"; for (var i = 0; i < check.length; i++) { if (check[i] == green) { continue; } else { var statusCell = sheet.getRange((i+2), checkColumn, 1, 1); var urlCell = sheet.getRange((i+2), urlColumn, 1, 1); var dataRow = sheet.getRange((i+2), 1, 1, (lastColumn - 2)); function mergeTasks() { function docCreator() { var docTemplate1 = DriveApp.getFileById("templateId1"); //allows for if statements to determine which template is needed //var docTemplate2 = DriveApp.getFileById("templateId2"); var folderDestination1 = DriveApp.getFolderById("folderId1"); var folderDestination2 = DriveApp.getFolderById("folderId2"); if (condition1 == met) { var docToUse = docTemplate1; var folderDestination = folderDestination1 var emailTemplate = HtmlService.createHtmlOutputFromFile("Email Template 1").getContent(); } else if (condition2 == met) { var docToUse = docTemplate2; var folderDestination = folderDestination2 var emailTemplate = HtmlService.createHtmlOutputFromFile("Email Template 2").getContent(); } var docName = "Name - " + variable + "string"; var docCopy = docToUse.makeCopy(docName, folderDestination); var docId = docCopy.getId(); var docURL = DriveApp.getFileById(docId).getUrl(); var docToSend = DriveApp.getFileById(docId); var docInUse = DocumentApp.openById(docId); var docBody = docInUse.getBody(); var docText = docBody.getText(); function tagReplace() { var taggedArray = docText.match(/\<{2}[\w\d\S]+\>{2}/g); var headerArray = sheet.getRange(1, 1, 1, (lastColumn - 2)).getValues(); var dataArray = dataRow.getValues(); var strippedArray = []; function tagStrip() { for (var t = 0; t < taggedArray.length; t++) { strippedArray.push(taggedArray[t].toString().slice(2, -2)); } } function dataMatch() { for (var s = 0; s < strippedArray.length; s++) { for (var h = 0; h < headerArray[0].length; h++) { if (strippedArray[s] == headerArray[0][h]) { docBody.replaceText(taggedArray[s], dataArray[0][h]); } } } docInUse.saveAndClose(); } tagStrip(); dataMatch(); } function emailCreator() { var emailTag = "email@address.com"; var bodyAddition = '<table style="border:1px; padding:15px; background-color:#DDDDDD"><tr><td> This is an HTML additive:</td><td><a href = "' + docURL + '">' + docName + '</a></td></tr></table><br /><br />'; var emailBody = emailTemplate + bodyAddition; var emailSubject = "New Email " + docName + " string" MailApp.sendEmail({ to: emailTag, subject: emailSubject, htmlBody: emailBody, }); } tagReplace(); statusCell.setBackground(yellow); emailCreator(); urlCell.setValue(docURL); } statusCell.setBackground(red); docCreator(); statusCell.setBackground(green); } mergeTasks(); } } } checkAndComplete(); } 

为此,您的Google表格可以具有任意数量的列,只需一个标题行(冻结即可),并在最后两列。 最后一列是URL,倒数第二列是Check(显示背景状态的颜色)。

您的Google文档可以根据您的需要进行书写/格式化,但是使用<<>>标记来replace表格中数据的位置; 比如 – <<staffName>> 。 这个标签(find并使用RegExreplace)需要匹配find数据的列标题。 例如,如果列3具有名称,并在第一个单元格中被称为PersonName,则使用标签<<PersonName>>

GAS允许创buildHTML文件,并且可以根据需要将其写成复杂/裸露的格式,并且可以通过GAS代码进行修改。 正如您所描述的,您希望用电子邮件replace电子邮件中的标签。 您可以用类似的方法来完成这个工作,以replaceGoogle文档中的标签。 您可以在这里的 Mail方法的GAS参考中find更多的信息,在这里可以find更多的HTML方法。

此代码没有行限制器。 GAS允许在代码的一次运行中进行一次/多次调用。 如果是这种情况,可以使用时间触发器简单地调用该函数,并且将从停止的任何时间点以一定的时间间隔重新运行。