VBA JavaScript object does not support this property or method

I am trying to get a text statistics function from https://github.com/cgiffard/TextStatistics.js/blob/master/index.js

Work in Excel

I cut JavaScript code to reduce concatenation

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('</'+t+'>','.')});e=e.replace(/<[^>]+>/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(/[^az]+/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(/^[AZ]/)||n){if(i.syllableCount(e)>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(/[^az]/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'&&module.exports?module.exports=r:typeof define!='undefined'?define('textstatistics',[],function(){return r}):e.textstatistics=r})(this);" 'code = code + " return textstatistics(s).fleschKincaidReadingEase();" & _ '"return stat.fleschKincaidReadingEase();" & _ 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 

I get an object that does not support this property or method - I think this is due to the creation of text statistics.

Do I need to convert javascript to just a set of functions?

UPDATE: A slightly different approach using eval

 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('</'+t+'>','.')});e=e.replace(/<[^>]+>/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;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;" & _ "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(/[^az]+/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;" & _ "var r=0,i=this;n=n===false?false:true;e.split(/\s+/).forEach(function(e){if(!e.match(/^[AZ]/)||n){if(i.syllableCount(e)>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(/[^az]/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)$/];" & _ "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'&&module.exports?module.exports=r:typeof define!='undefined'?define('textstatistics',[],function(){return r}):e.textstatistics=r})(this);" & _ "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 

JSFiddle shows that it works here http://jsfiddle.net/hwr26dkf/

UPDATE: 01/10/2014 Final VBA thanks to Michael Petick

 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('</'+t+'>','.')});e=e.replace(/<[^>]+>/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;" & _ "if(typeof e!='function')throw new TypeError;var n=arguments[1];for(var r=0;r<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>>>0;if(typeof e!=='function'){throw new TypeError}var r=[];var i=arguments.length>=2?arguments[1]:void 0;for(var s=0;s<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;" & _ "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};" & _ "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(/[^az]+/ig,'');return e.length};TextStatistics.prototype.sentenceCount=function(e){e=e?cleanText(e):this.text;" & _ "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;" & _ "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(/^[AZ]/)||t){if(r.syllableCount(e)>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};" & _ "TextStatistics.prototype.syllableCount=function(e){var t=0,n=0,r=0;e=e.toLowerCase().replace(/[^az]/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)$/];" & _ "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 
+1
source share
1 answer

I spent some time this afternoon exploring Javascript, and then tried to figure out what happens to your TextStatistics class when running in Microsoft ScriptControl . Instead of starting with garbled code in VBA, I went back to the code in github referenced by OP. The first thing I discovered is that ScriptControl will parse and execute an anonymous global function, but as soon as this code is added to ScriptControl, it seems to lose track of the TextStatistics object. So, the first thing I did was simply remove the anonymous global function by deleting it at the top:

 (function(glob) { 

and deleting this line below:

 (typeof module != "undefined" && module.exports) ? (module.exports = textStatistics) : (typeof define != "undefined" ? (define("textstatistics", [], function() { return textStatistics; })) : (glob.textstatistics = textStatistics)); })(this); 

As soon as I deleted this as a source of problems, I found that I could create new instances of TextStatistics , but I could not assign them text correctly. Neither as a parameter using new , or by calling a method of type sentenceCount() . It puzzled me. Since creating an instance of TextStatistics cannot be performed properly, I decided to look at the constructor. It is simple but called cleanText . One thing that stood out with me was forEach . As a guess, I worked a bit on Javascript / ScriptControl, and then for each. I found out that ScriptControl uses ECMAScript, not Javascript. As soon as I got this straight, I found a link with this information that includes this comment: about the forEach method:

This method is an extension of the ECMA-262 JavaScript standard; as such, it cannot be present in other implementations of the standard. For it to work, you need to add the following code at the top of your script:

And this code:

 if (!Array.prototype.forEach) { Array.prototype.forEach = function (fun /*, thisp*/ ) { var len = this.length; if (typeof fun != 'function') throw new TypeError(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) fun.call(thisp, this[i], i, this); } }; } 

After providing my initial answer, the OP found that functions containing syllables do not work. There is another feature that appeared in the later ECMA specification, which was not supported by ScriptControl . It was a polyfill filter function on arrays. According to this Mozilla documentation :

a filter was added to the ECMA-262 standard in the fifth edition; as such, it cannot be present in all implementations of the standard. You can get around this by inserting the following code at the beginning of your scripts, allowing you to use the filter in implementations of ECMA-262 that do not support it.

The given code complies with the specification:

 if (!Array.prototype.filter) { Array.prototype.filter = function(fun/*, thisArg*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; if (typeof fun !== 'function') { throw new TypeError(); } var res = []; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; i++) { if (i in t) { var val = t[i]; // NOTE: Technically this should Object.defineProperty at // the next index, as push can be affected by // properties on Object.prototype and Array.prototype. // But that method new, and collisions should be // rare, so use the more-compatible alternative. if (fun.call(thisArg, val, i, t)) { res.push(val); } } } return res; }; } 

Was it that simple? Was this the cause of these problems? Yes, that was so. I added that the code at the top of the script and VBA and ScriptControl were content. Therefore, before converting and converting everything " to ' , the Javascript code looks like this:

 if (!Array.prototype.forEach) { Array.prototype.forEach = function (fun /*, thisp*/ ) { var len = this.length; if (typeof fun != 'function') throw new TypeError(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) fun.call(thisp, this[i], i, this); } }; } if (!Array.prototype.filter) { Array.prototype.filter = function(fun/*, thisArg*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; if (typeof fun !== 'function') { throw new TypeError(); } var res = []; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; i++) { if (i in t) { var val = t[i]; // NOTE: Technically this should Object.defineProperty at // the next index, as push can be affected by // properties on Object.prototype and Array.prototype. // But that method new, and collisions should be // rare, so use the more-compatible alternative. if (fun.call(thisArg, val, i, t)) { res.push(val); } } } return res; }; } function cleanText(text) { // all these tags should be preceeded by a full stop. var fullStopTags = ['li', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dd']; fullStopTags.forEach(function (tag) { text = text.replace('</' + tag + '>', '.'); }); text = text.replace(/<[^>]+>/g, '') // Strip tags .replace(/[,:;()\-]/, ' ') // Replace commans, hyphens etc (count them as spaces) .replace(/[\.!?]/, '.') // Unify terminators .replace(/^\s+/, '') // Strip leading whitespace .replace(/[ ]*(\n|\r\n|\r)[ ]*/, ' ') // Replace new lines with spaces .replace(/([\.])[\. ]+/, '.') // Check for duplicated terminators .replace(/[ ]*([\.])/, '. ') // Pad sentence terminators .replace(/\s+/, ' ') // Remove multiple spaces .replace(/\s+$/, ''); // Strip trailing whitespace text += '.'; // Add final terminator, just in case it missing. return text; } var TextStatistics = function TextStatistics(text) { this.text = text ? cleanText(text) : this.text; }; TextStatistics.prototype.fleschKincaidReadingEase = function (text) { text = text ? cleanText(text) : this.text; return Math.round((206.835 - (1.015 * this.averageWordsPerSentence(text)) - (84.6 * this.averageSyllablesPerWord(text))) * 10) / 10; }; TextStatistics.prototype.fleschKincaidGradeLevel = function (text) { text = text ? cleanText(text) : this.text; return Math.round(((0.39 * this.averageWordsPerSentence(text)) + (11.8 * this.averageSyllablesPerWord(text)) - 15.59) * 10) / 10; }; TextStatistics.prototype.gunningFogScore = function (text) { text = text ? cleanText(text) : this.text; return Math.round(((this.averageWordsPerSentence(text) + this.percentageWordsWithThreeSyllables(text, false)) * 0.4) * 10) / 10; }; TextStatistics.prototype.colemanLiauIndex = function (text) { text = text ? cleanText(text) : this.text; return Math.round(((5.89 * (this.letterCount(text) / this.wordCount(text))) - (0.3 * (this.sentenceCount(text) / this.wordCount(text))) - 15.8) * 10) / 10; }; TextStatistics.prototype.smogIndex = function (text) { text = text ? cleanText(text) : this.text; return Math.round(1.043 * Math.sqrt((this.wordsWithThreeSyllables(text) * (30 / this.sentenceCount(text))) + 3.1291) * 10) / 10; }; TextStatistics.prototype.automatedReadabilityIndex = function (text) { text = text ? cleanText(text) : this.text; return Math.round(((4.71 * (this.letterCount(text) / this.wordCount(text))) + (0.5 * (this.wordCount(text) / this.sentenceCount(text))) - 21.43) * 10) / 10; }; TextStatistics.prototype.textLength = function (text) { text = text ? cleanText(text) : this.text; return text.length; }; TextStatistics.prototype.letterCount = function (text) { text = text ? cleanText(text) : this.text; text = text.replace(/[^az]+/ig, ''); return text.length; }; TextStatistics.prototype.sentenceCount = function (text) { text = text ? cleanText(text) : this.text; // Will be tripped up by 'Mr.' or 'UK'. Not a major concern at this point. return text.replace(/[^\.!?]/g, '').length || 1; }; TextStatistics.prototype.wordCount = function (text) { text = text ? cleanText(text) : this.text; return text.split(/[^a-z0-9]+/i).length || 1; }; TextStatistics.prototype.averageWordsPerSentence = function (text) { text = text ? cleanText(text) : this.text; return this.wordCount(text) / this.sentenceCount(text); }; TextStatistics.prototype.averageSyllablesPerWord = function (text) { text = text ? cleanText(text) : this.text; var syllableCount = 0, wordCount = this.wordCount(text), self = this; text.split(/\s+/).forEach(function (word) { syllableCount += self.syllableCount(word); }); // Prevent NaN... return (syllableCount || 1) / (wordCount || 1); }; TextStatistics.prototype.wordsWithThreeSyllables = function (text, countProperNouns) { text = text ? cleanText(text) : this.text; var longWordCount = 0, self = this; countProperNouns = countProperNouns === false ? false : true; text.split(/\s+/).forEach(function (word) { // We don't count proper nouns or capitalised words if the countProperNouns attribute is set. // Defaults to true. if (!word.match(/^[AZ]/) || countProperNouns) { if (self.syllableCount(word) > 2) longWordCount++; } }); return longWordCount; }; TextStatistics.prototype.percentageWordsWithThreeSyllables = function (text, countProperNouns) { text = text ? cleanText(text) : this.text; return (this.wordsWithThreeSyllables(text, countProperNouns) / this.wordCount(text)) * 100; }; TextStatistics.prototype.syllableCount = function (word) { var syllableCount = 0, prefixSuffixCount = 0, wordPartCount = 0; // Prepare word - make lower case and remove non-word characters word = word.toLowerCase().replace(/[^az]/g, ''); // Specific common exceptions that don't follow the rule set below are handled individually // Array of problem words (with word as key, syllable count as value) var problemWords = { 'simile': 3, 'forever': 3, 'shoreline': 2 }; // Return if we've hit one of those... if (problemWords.hasOwnProperty(word)) return problemWords[word]; // These syllables would be counted as two but should be one var subSyllables = [ /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]+$/, // Sorts out deal, deign etc /[aeiouy]rse$/ // Purse, hearse ]; // These syllables would be counted as one but should be two var addSyllables = [ /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)$/]; // Single syllable prefixes and suffixes var prefixSuffix = [ /^un/, /^fore/, /ly$/, /less$/, /ful$/, /ers?$/, /ings?$/]; // Remove prefixes and suffixes and count how many were taken prefixSuffix.forEach(function (regex) { if (word.match(regex)) { word = word.replace(regex, ''); prefixSuffixCount++; } }); wordPartCount = word.split(/[^aeiouy]+/ig) .filter(function (wordPart) { return !!wordPart.replace(/\s+/ig, '').length; }) .length; // Get preliminary syllable count... syllableCount = wordPartCount + prefixSuffixCount; // Some syllables do not follow normal rules - check for them subSyllables.forEach(function (syllable) { if (word.match(syllable)) syllableCount--; }); addSyllables.forEach(function (syllable) { if (word.match(syllable)) syllableCount++; }); return syllableCount || 1; }; function textStatistics(text) { return new TextStatistics(text); } 

After executing this function and adding it to the code variable (see OP Visual Basic code), I was able to create an instance of this control and call its methods. There are several ways to use TextStatistics in VBA:

 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('</'+t+'>','.')});e=e.replace(/<[^>]+>/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.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>>>0;if(typeof e!=='function'){throw new TypeError}var r=[];var i=arguments.length>=2?arguments[1]:void 0;for(var s=0;s<n;s++){if(s in t){var o=t[s];if(e.call(i,o,s,t)){r.push(o)}}}return r}}if(!Array.prototype.forEach){Array.prototype.forEach=function(e){var t=this.length;if(typeof e!='function')throw new TypeError;var n=arguments[1];for(var r=0;r<t;r++){if(r in this)e.call(n,this[r],r,this)}}}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;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};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(/[^az]+/ig,'');return e.length};TextStatistics.prototype.sentenceCount=function(e){e=e?cleanText(e):this.text;" & _ "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;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(/^[AZ]/)||t){if(r.syllableCount(e)>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};TextStatistics.prototype.syllableCount=function(e){var t=0,n=0,r=0;e=e.toLowerCase().replace(/[^az]/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)$/];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}" s1 = "the quick brown fox jumps over the lazy dog" s2 = "help me! Some Short sentence fragments. Just a test" 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.wordCount(s1) sc = oTextStats.sentenceCount(s2) ' 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('" + s1 + "')") wc = oTextStats.wordCount("") sc = oTextStats.sentenceCount("") End With 
+2
source

Source: https://habr.com/ru/post/975851/


All Articles