title: VBA JavaScript object doesn't support this property or method
body: <p>Im trying to get the Text Statistics function from <a href="https://github.com/cgiffard/TextStatistics.js/blob/master/index.js" rel="nofollow">https://github.com/cgiffard/TextStatistics.js/blob/master/index.js</a></p>
  
  <p>Working in Excel</p>
  
  <p>I have minified the JavaScript code to shorten the concatenations</p>
  
  <pre><code>Function Text_Statistics1(textString As String)
  
  Dim code As String
  
  code = "function text_stats(teststringtoprocess){(function(e){function t(e){var t=['li','p','h1','h2','h3','h4','h5','h6','dd'];t.forEach(function(t){e=e.replace('&lt;/'+t+'&gt;','.')});e=e.replace(/&lt;[^&gt;]+&gt;/g,'').replace(/[,:;()\-]/,' ').replace(/[\.!?]/,'.').replace(/^\s+/,'').replace(/[ ]*(\n|\r\n|\r)[ ]*/,' ').replace(/([\.])[\. ]+/,'.').replace(/[ ]*([\.])/,'. ').replace(/\s+/,' ').replace(/\s+$/,'');e+='.';return e}function r(e){return new n(e)}var n=function(n){this.text=n?t(n):this.text};n.prototype.fleschKincaidReadingEase=function(e){e=e?t(e):this.text;return Math.round((206.835-1.015*this.averageWordsPerSentence(e)-84.6*this.averageSyllablesPerWord(e))*10)/10};n.prototype.fleschKincaidGradeLevel=function(e){e=e?t(e):this.text;return Math.round((.39*this.averageWordsPerSentence(e)+11.8*this.averageSyllablesPerWord(e)-15.59)*10)/10};n.prototype.gunningFogScore=function(e){e=e?t(e):this.text;"
  code = code + "return Math.round((this.averageWordsPerSentence(e)+this.percentageWordsWithThreeSyllables(e,false))*.4*10)/10};n.prototype.colemanLiauIndex=function(e){e=e?t(e):this.text;return Math.round((5.89*(this.letterCount(e)/this.wordCount(e))-.3*(this.sentenceCount(e)/this.wordCount(e))-15.8)*10)/10};n.prototype.smogIndex=function(e){e=e?t(e):this.text;return Math.round(1.043*Math.sqrt(this.wordsWithThreeSyllables(e)*(30/this.sentenceCount(e))+3.1291)*10)/10};n.prototype.automatedReadabilityIndex=function(e){e=e?t(e):this.text;"
  code = code + "return Math.round((4.71*(this.letterCount(e)/this.wordCount(e))+.5*(this.wordCount(e)/this.sentenceCount(e))-21.43)*10)/10};n.prototype.textLength=function(e){e=e?t(e):this.text;return e.length};n.prototype.letterCount=function(e){e=e?t(e):this.text;e=e.replace(/[^a-z]+/ig,'');return e.length};n.prototype.sentenceCount=function(e){e=e?t(e):this.text;return e.replace(/[^\.!?]/g,'').length||1};n.prototype.wordCount=function(e){e=e?t(e):this.text;return e.split(/[^a-z0-9]+/i).length||1};n.prototype.averageWordsPerSentence=function(e){e=e?t(e):this.text;"
  code = code + "return this.wordCount(e)/this.sentenceCount(e)};n.prototype.averageSyllablesPerWord=function(e){e=e?t(e):this.text;var n=0,r=this.wordCount(e),i=this;e.split(/\s+/).forEach(function(e){n+=i.syllableCount(e)});return(n||1)/(r||1)};n.prototype.wordsWithThreeSyllables=function(e,n){e=e?t(e):this.text;var r=0,i=this;n=n===false?false:true;e.split(/\s+/).forEach(function(e){if(!e.match(/^[A-Z]/)||n){if(i.syllableCount(e)&gt;2)r++}});return r};n.prototype.percentageWordsWithThreeSyllables=function(e,n){e=e?t(e):this.text;return this.wordsWithThreeSyllables(e,n)/this.wordCount(e)*100};n.prototype.syllableCount=function(e){var t=0,n=0,r=0;e=e.toLowerCase().replace(/[^a-z]/g,'');var i={simile:3,forever:3,shoreline:2};if(i.hasOwnProperty(e))return i[e];var s=[/cial/,/tia/,/cius/,/cious/,/giu/,/ion/,/iou/,/sia$/,/[^aeiuoyt]{2,}ed$/,/.ely$/,/[cg]h?e[rsd]?$/,/rved?$/,/[aeiouy][dt]es?$/,/[aeiouy][^aeiouydt]e[rsd]?$/,/^[dr]e[aeiou][^aeiou]+$/,/[aeiouy]rse$/];"
  code = code + "var o=[/ia/,/riet/,/dien/,/iu/,/io/,/ii/,/[aeiouym]bl$/,/[aeiou]{3}/,/^mc/,/ism$/,/([^aeiouy])\1l$/,/[^l]lien/,/^coa[dglx]./,/[^gq]ua[^auieo]/,/dnt$/,/uity$/,/ie(r|st)$/];var u=[/^un/,/^fore/,/ly$/,/less$/,/ful$/,/ers?$/,/ings?$/];u.forEach(function(t){if(e.match(t)){e=e.replace(t,'');n++}});r=e.split(/[^aeiouy]+/ig).filter(function(e){return!!e.replace(/\s+/ig,'').length}).length;t=r+n;s.forEach(function(n){if(e.match(n))t--});o.forEach(function(n){if(e.match(n))t++});return t||1};typeof module!='undefined'&amp;&amp;module.exports?module.exports=r:typeof define!='undefined'?define('textstatistics',[],function(){return r}):e.textstatistics=r})(this);"
  
  'code = code + " return textstatistics(s).fleschKincaidReadingEase();" &amp; _
  '"return stat.fleschKincaidReadingEase();" &amp; _
  
  code = code + "return textstatistics(teststringtoprocess).fleschKincaidReadingEase();}"
  'code = code + "return textstatistics(teststringtoprocess);}"
  
  
  
  Dim o As New ScriptControl
      o.Language = "JScript"
      With o
          .AddCode code
          Text_Statistics1 = .Run("text_stats", textString)
      End With
  
  End Function
  </code></pre>
  
  <p>I'm getting object doesn't support this property or method - I think its due to the instantiation of Text Statistics.</p>
  
  <p>Do I need to convert the javascript to just be a set of functions?</p>
  
  <p><strong>UPDATE:</strong>
  Slightly different approach using eval</p>
  
  <pre><code>Function Text_Stat(textString As String, textstat As String)
  
  Dim code As String
  
  code = "(function(e){function t(e){var t=['li','p','h1','h2','h3','h4','h5','h6','dd'];t.forEach(function(t){e=e.replace('&lt;/'+t+'&gt;','.')});e=e.replace(/&lt;[^&gt;]+&gt;/g,'').replace(/[,:;()\-]/,' ').replace(/[\.!?]/,'.').replace(/^\s+/,'').replace(/[ ]*(\n|\r\n|\r)[ ]*/,' ').replace(/([\.])[\. ]+/,'.').replace(/[ ]*([\.])/,'. ').replace(/\s+/,' ').replace(/\s+$/,'');e+='.';return e}function r(e){return new n(e)}var n=function(n){this.text=n?t(n):this.text};n.prototype.fleschKincaidReadingEase=function(e){e=e?t(e):this.text;return Math.round((206.835-1.015*this.averageWordsPerSentence(e)-84.6*this.averageSyllablesPerWord(e))*10)/10};n.prototype.fleschKincaidGradeLevel=function(e){e=e?t(e):this.text;" &amp; _
  "return Math.round((.39*this.averageWordsPerSentence(e)+11.8*this.averageSyllablesPerWord(e)-15.59)*10)/10};n.prototype.gunningFogScore=function(e){e=e?t(e):this.text;return Math.round((this.averageWordsPerSentence(e)+this.percentageWordsWithThreeSyllables(e,false))*.4*10)/10};n.prototype.colemanLiauIndex=function(e){e=e?t(e):this.text;return Math.round((5.89*(this.letterCount(e)/this.wordCount(e))-.3*(this.sentenceCount(e)/this.wordCount(e))-15.8)*10)/10};n.prototype.smogIndex=function(e){e=e?t(e):this.text;return Math.round(1.043*Math.sqrt(this.wordsWithThreeSyllables(e)*(30/this.sentenceCount(e))+3.1291)*10)/10};n.prototype.automatedReadabilityIndex=function(e){e=e?t(e):this.text;" &amp; _
  "return Math.round((4.71*(this.letterCount(e)/this.wordCount(e))+.5*(this.wordCount(e)/this.sentenceCount(e))-21.43)*10)/10};n.prototype.textLength=function(e){e=e?t(e):this.text;return e.length};n.prototype.letterCount=function(e){e=e?t(e):this.text;e=e.replace(/[^a-z]+/ig,'');return e.length};n.prototype.sentenceCount=function(e){e=e?t(e):this.text;return e.replace(/[^\.!?]/g,'').length||1};n.prototype.wordCount=function(e){e=e?t(e):this.text;return e.split(/[^a-z0-9]+/i).length||1};n.prototype.averageWordsPerSentence=function(e){e=e?t(e):this.text;return this.wordCount(e)/this.sentenceCount(e)};n.prototype.averageSyllablesPerWord=function(e){e=e?t(e):this.text;var n=0,r=this.wordCount(e),i=this;e.split(/\s+/).forEach(function(e){n+=i.syllableCount(e)});return(n||1)/(r||1)};n.prototype.wordsWithThreeSyllables=function(e,n){e=e?t(e):this.text;" &amp; _
  "var r=0,i=this;n=n===false?false:true;e.split(/\s+/).forEach(function(e){if(!e.match(/^[A-Z]/)||n){if(i.syllableCount(e)&gt;2)r++}});return r};n.prototype.percentageWordsWithThreeSyllables=function(e,n){e=e?t(e):this.text;" &amp; _
  "return this.wordsWithThreeSyllables(e,n)/this.wordCount(e)*100};n.prototype.syllableCount=function(e){var t=0,n=0,r=0;e=e.toLowerCase().replace(/[^a-z]/g,'');var i={simile:3,forever:3,shoreline:2};if(i.hasOwnProperty(e))return i[e];var s=[/cial/,/tia/,/cius/,/cious/,/giu/,/ion/,/iou/,/sia$/,/[^aeiuoyt]{2,}ed$/,/.ely$/,/[cg]h?e[rsd]?$/,/rved?$/,/[aeiouy][dt]es?$/,/[aeiouy][^aeiouydt]e[rsd]?$/,/^[dr]e[aeiou][^aeiou]+$/,/[aeiouy]rse$/];var o=[/ia/,/riet/,/dien/,/iu/,/io/,/ii/,/[aeiouym]bl$/,/[aeiou]{3}/,/^mc/,/ism$/,/([^aeiouy])\1l$/,/[^l]lien/,/^coa[dglx]./,/[^gq]ua[^auieo]/,/dnt$/,/uity$/,/ie(r|st)$/];" &amp; _
  "var u=[/^un/,/^fore/,/ly$/,/less$/,/ful$/,/ers?$/,/ings?$/];u.forEach(function(t){if(e.match(t)){e=e.replace(t,'');n++}});r=e.split(/[^aeiouy]+/ig).filter(function(e){return!!e.replace(/\s+/ig,'').length}).length;t=r+n;s.forEach(function(n){if(e.match(n))t--});o.forEach(function(n){if(e.match(n))t++});return t||1};typeof module!='undefined'&amp;&amp;module.exports?module.exports=r:typeof define!='undefined'?define('textstatistics',[],function(){return r}):e.textstatistics=r})(this);" &amp; _
  "var stat = new textstatistics('Your text here');alert(stat.sentenceCount('This. dfgdfg. is. a. long. sentence.'));"
  
  
  Dim o As New ScriptControl
      o.Language = "JScript"
      With o
          .AllowUI = True
          .AddCode code
          .Eval "stat.sentenceCount('This. dfgdfg. is. a. long. sentence.')"
          'result = .Eval(code)
          'Debug.Print .Eval("'Hello World'.substring(1, 4);")
          'result = .Eval(result)
          'Text_Stat = .Run(result)
      End With
  
  End Function
  </code></pre>
  
  <p>JSFiddle shows it working here <a href="http://jsfiddle.net/hwr26dkf/" rel="nofollow">http://jsfiddle.net/hwr26dkf/</a></p>
  
  <p>UPDATE: 01/10/2014
  Final Working VBA version thanks to Michael Petch</p>
  
  <pre><code>Function Text_Statistics(statType As Integer, textString As String)
  
  Dim wc, sc As Integer
  Dim s1, s2, code As String
  Dim oTextStats As Object
  Dim o As New ScriptControl
  
  code = "function cleanText(e){var t=['li','p','h1','h2','h3','h4','h5','h6','dd'];t.forEach(function(t){e=e.replace('&lt;/'+t+'&gt;','.')});e=e.replace(/&lt;[^&gt;]+&gt;/g,'').replace(/[,:;()\-]/,' ').replace(/[\.!?]/,'.').replace(/^\s+/,'').replace(/[ ]*(\n|\r\n|\r)[ ]*/,' ').replace(/([\.])[\. ]+/,'.').replace(/[ ]*([\.])/,'. ').replace(/\s+/,' ').replace(/\s+$/,'');e+='.';return e}function textStatistics(e){return new TextStatistics(e)}if(!Array.prototype.forEach){Array.prototype.forEach=function(e){var t=this.length;" &amp; _
  "if(typeof e!='function')throw new TypeError;var n=arguments[1];for(var r=0;r&lt;t;r++){if(r in this)e.call(n,this[r],r,this)}}}if(!Array.prototype.filter){Array.prototype.filter=function(e){'use strict';if(this===void 0||this===null){throw new TypeError}var t=Object(this);var n=t.length&gt;&gt;&gt;0;if(typeof e!=='function'){throw new TypeError}var r=[];var i=arguments.length&gt;=2?arguments[1]:void 0;for(var s=0;s&lt;n;s++){if(s in t){var o=t[s];if(e.call(i,o,s,t)){r.push(o)}}}return r}}var TextStatistics=function(t){this.text=t?cleanText(t):this.text};TextStatistics.prototype.fleschKincaidReadingEase=function(e){e=e?cleanText(e):this.text;return Math.round((206.835-1.015*this.averageWordsPerSentence(e)-84.6*this.averageSyllablesPerWord(e))*10)/10};TextStatistics.prototype.fleschKincaidGradeLevel=function(e){e=e?cleanText(e):this.text;" &amp; _
  "return Math.round((.39*this.averageWordsPerSentence(e)+11.8*this.averageSyllablesPerWord(e)-15.59)*10)/10};TextStatistics.prototype.gunningFogScore=function(e){e=e?cleanText(e):this.text;return Math.round((this.averageWordsPerSentence(e)+this.percentageWordsWithThreeSyllables(e,false))*.4*10)/10};TextStatistics.prototype.colemanLiauIndex=function(e){e=e?cleanText(e):this.text;return Math.round((5.89*(this.letterCount(e)/this.wordCount(e))-.3*(this.sentenceCount(e)/this.wordCount(e))-15.8)*10)/10};" &amp; _
  "TextStatistics.prototype.smogIndex=function(e){e=e?cleanText(e):this.text;return Math.round(1.043*Math.sqrt(this.wordsWithThreeSyllables(e)*(30/this.sentenceCount(e))+3.1291)*10)/10};TextStatistics.prototype.automatedReadabilityIndex=function(e){e=e?cleanText(e):this.text;return Math.round((4.71*(this.letterCount(e)/this.wordCount(e))+.5*(this.wordCount(e)/this.sentenceCount(e))-21.43)*10)/10};TextStatistics.prototype.textLength=function(e){e=e?cleanText(e):this.text;return e.length};TextStatistics.prototype.letterCount=function(e){e=e?cleanText(e):this.text;e=e.replace(/[^a-z]+/ig,'');return e.length};TextStatistics.prototype.sentenceCount=function(e){e=e?cleanText(e):this.text;" &amp; _
  "return e.replace(/[^\.!?]/g,'').length||1};TextStatistics.prototype.wordCount=function(e){e=e?cleanText(e):this.text;return e.split(/[^a-z0-9]+/i).length||1};TextStatistics.prototype.averageWordsPerSentence=function(e){e=e?cleanText(e):this.text;return this.wordCount(e)/this.sentenceCount(e)};TextStatistics.prototype.averageSyllablesPerWord=function(e){e=e?cleanText(e):this.text;" &amp; _
  "var t=0,n=this.wordCount(e),r=this;e.split(/\s+/).forEach(function(e){t+=r.syllableCount(e)});return(t||1)/(n||1)};TextStatistics.prototype.wordsWithThreeSyllables=function(e,t){e=e?cleanText(e):this.text;var n=0,r=this;t=t===false?false:true;e.split(/\s+/).forEach(function(e){if(!e.match(/^[A-Z]/)||t){if(r.syllableCount(e)&gt;2)n++}});return n};TextStatistics.prototype.percentageWordsWithThreeSyllables=function(e,t){e=e?cleanText(e):this.text;return this.wordsWithThreeSyllables(e,t)/this.wordCount(e)*100};" &amp; _
  "TextStatistics.prototype.syllableCount=function(e){var t=0,n=0,r=0;e=e.toLowerCase().replace(/[^a-z]/g,'');var i={simile:3,forever:3,shoreline:2};if(i.hasOwnProperty(e))return i[e];var s=[/cial/,/tia/,/cius/,/cious/,/giu/,/ion/,/iou/,/sia$/,/[^aeiuoyt]{2,}ed$/,/.ely$/,/[cg]h?e[rsd]?$/,/rved?$/,/[aeiouy][dt]es?$/,/[aeiouy][^aeiouydt]e[rsd]?$/,/^[dr]e[aeiou][^aeiou]+$/,/[aeiouy]rse$/];var o=[/ia/,/riet/,/dien/,/iu/,/io/,/ii/,/[aeiouym]bl$/,/[aeiou]{3}/,/^mc/,/ism$/,/([^aeiouy])\1l$/,/[^l]lien/,/^coa[dglx]./,/[^gq]ua[^auieo]/,/dnt$/,/uity$/,/ie(r|st)$/];" &amp; _
  "var u=[/^un/,/^fore/,/ly$/,/less$/,/ful$/,/ers?$/,/ings?$/];u.forEach(function(t){if(e.match(t)){e=e.replace(t,'');n++}});r=e.split(/[^aeiouy]+/ig).filter(function(e){return!!e.replace(/\s+/ig,'').length}).length;t=r+n;s.forEach(function(n){if(e.match(n))t--});o.forEach(function(n){if(e.match(n))t++});return t||1}"
  
  With o
      .Language = "JScript"
      .AddCode code
      ' Create a TextStatistics object initially with no text.
      ' textStatistics is a function that creates TextStatistics objects
      Set oTextStats = .Eval("textStatistics()")
  
      ' Now simply call TextStatistics methods directly
      wc = oTextStats.averageWordsPerSentence(textString)
      sc = oTextStats.syllableCount(textString)
  
      ' Alternatively you can create a TextStatistics object with the text
      ' and call the methods with a blank string to return the values
      ' for the string passed in the constructor
  
      'Set oTextStats = .Eval("textStatistics('" + textString + "')")
      'wc = oTextStats.wordCount("")
      'sc = oTextStats.sentenceCount("")
  
  
      Select Case statType
      Case 1
          Text_Statistics = oTextStats.wordCount(textString)
      Case 2
          Text_Statistics = oTextStats.sentenceCount(textString)
      Case 3
          Text_Statistics = oTextStats.fleschKincaidReadingEase(textString)
      Case 4
          Text_Statistics = oTextStats.fleschKincaidGradeLevel(textString)
      Case 5
          Text_Statistics = oTextStats.gunningFogScore(textString)
      Case 6
          Text_Statistics = oTextStats.colemanLiauIndex(textString)
      Case 7
          Text_Statistics = oTextStats.smogIndex(textString)
      Case 8
          Text_Statistics = oTextStats.automatedReadabilityIndex(textString)
      Case 9
          Text_Statistics = oTextStats.textLength(textString)
     Case 10
          Text_Statistics = oTextStats.letterCount(textString)
     Case 11
          Text_Statistics = oTextStats.averageWordsPerSentence(textString)
     Case 12
          Text_Statistics = oTextStats.averageSyllablesPerWord(textString)
  
  End Select
  
  End With
  End Function
  </code></pre>