├── Lib ├── ExcelDna.Integration │ ├── AssemblyLoader.cs │ ├── AssemblyLoaderExcelServer.cs │ ├── AssemblyReference.cs │ ├── ComInterop.cs │ ├── ComRegistration.cs │ ├── ComServer.cs │ ├── CreateDnaLibrarySerializer.bat │ ├── DnaLibrary.cs │ ├── DnaLibrarySerialization.cs │ ├── Excel.cs │ ├── ExcelAsyncHandle.cs │ ├── ExcelAsyncUtil.cs │ ├── ExcelAttributes.cs │ ├── ExcelComAddIn.cs │ ├── ExcelCommandBars.cs │ ├── ExcelCustomTaskPane.cs │ ├── ExcelDna.Integration.csproj │ ├── ExcelDna.Integration.vs2008.csproj │ ├── ExcelError.cs │ ├── ExcelIntegration.cs │ ├── ExcelReference.cs │ ├── ExcelRibbon.cs │ ├── ExcelRtd.cs │ ├── ExcelRtd2010BugHelper.cs │ ├── ExcelRtdObserver.cs │ ├── ExcelRtdServer.cs │ ├── ExcelSynchronizationContext.cs │ ├── ExportedAssembly.cs │ ├── ExternalLibrary.cs │ ├── GuidUtility.cs │ ├── IExcelAddIn.cs │ ├── LogDisplay.Designer.cs │ ├── LogDisplay.cs │ ├── LogDisplay.resx │ ├── MenuManager.cs │ ├── Project.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Reference.cs │ ├── RegistrationInfo.cs │ ├── SourceItem.cs │ ├── XlCall.cs │ └── bin │ │ ├── Release │ │ └── ExcelDna.Integration.dll │ │ ├── x64 │ │ └── Release │ │ │ └── ExcelDna.Integration.dll │ │ └── x86 │ │ └── Release │ │ └── ExcelDna.Integration.dll └── Extract4 │ ├── Enums.cs │ ├── Extract4.csproj │ ├── Properties │ └── AssemblyInfo.cs │ ├── Web │ └── Extractor_for_Web.cs │ ├── bin │ ├── x64 │ │ └── Release │ │ │ ├── Extract4.dll │ │ │ ├── HtmlAgilityPack.dll │ │ │ └── HtmlAgilityPack.xml │ └── x86 │ │ └── Release │ │ ├── Extract4.dll │ │ ├── HtmlAgilityPack.dll │ │ └── HtmlAgilityPack.xml │ └── packages.config ├── MarketDataDNA ├── MarketDataDNA.sln ├── MarketDataDNA │ ├── ExcelDNA.dna │ ├── ExcelDNA.xll │ ├── ExcelDNA64.dna │ ├── ExcelDNA64.xll │ ├── MarketDataDNA.csproj │ ├── MarketDataDNA_Method.cs │ ├── MarketDataDNA_RealTimeServer.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ └── bin │ │ ├── x64 │ │ └── Release │ │ │ ├── ExcelDNA64.dna │ │ │ ├── ExcelDNA64.xll │ │ │ ├── ExcelDna.Integration.dll │ │ │ ├── Extract4.dll │ │ │ ├── HtmlAgilityPack.dll │ │ │ ├── HtmlAgilityPack.xml │ │ │ └── MarketDataDNA.dll │ │ └── x86 │ │ └── Release │ │ ├── ExcelDNA.dna │ │ ├── ExcelDNA.xll │ │ ├── ExcelDna.Integration.dll │ │ ├── Extract4.dll │ │ ├── HtmlAgilityPack.dll │ │ ├── HtmlAgilityPack.xml │ │ └── MarketDataDNA.dll └── packages │ ├── Excel-DNA.0.30.3 │ ├── Excel-DNA.0.30.3.nupkg │ ├── Excel-DNA.0.30.3.nuspec │ ├── content │ │ └── ExcelDna-Template.dna │ ├── lib │ │ └── ExcelDna.Integration.dll │ ├── readme.txt │ └── tools │ │ ├── ExcelDna.Integration.dll │ │ ├── ExcelDna.xll │ │ ├── ExcelDna64.xll │ │ ├── ExcelDnaPack.exe │ │ ├── install.ps1 │ │ └── uninstall.ps1 │ ├── HtmlAgilityPack.1.4.6 │ ├── HAPIcon.png │ ├── HtmlAgilityPack.1.4.6.nupkg │ ├── HtmlAgilityPack.1.4.6.nuspec │ ├── lib │ │ ├── Net20 │ │ │ ├── HtmlAgilityPack.dll │ │ │ └── HtmlAgilityPack.xml │ │ ├── Net40-client │ │ │ ├── HtmlAgilityPack.dll │ │ │ └── HtmlAgilityPack.xml │ │ ├── Net40 │ │ │ ├── HtmlAgilityPack.XML │ │ │ └── HtmlAgilityPack.dll │ │ ├── Net45 │ │ │ ├── HtmlAgilityPack.XML │ │ │ └── HtmlAgilityPack.dll │ │ ├── sl3-wp │ │ │ ├── HtmlAgilityPack.XML │ │ │ └── HtmlAgilityPack.dll │ │ ├── sl4-windowsphone71 │ │ │ ├── HtmlAgilityPack.XML │ │ │ └── HtmlAgilityPack.dll │ │ ├── sl4 │ │ │ ├── HtmlAgilityPack.XML │ │ │ └── HtmlAgilityPack.dll │ │ ├── sl5 │ │ │ ├── HtmlAgilityPack.XML │ │ │ └── HtmlAgilityPack.dll │ │ └── winrt45 │ │ │ ├── HtmlAgilityPack.dll │ │ │ ├── HtmlAgilityPack.pri │ │ │ └── HtmlAgilityPack.xml │ └── readme.txt │ └── repositories.config └── README.md /Lib/ExcelDna.Integration/AssemblyLoaderExcelServer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using System.Diagnostics; 28 | using System.Reflection; 29 | using System.Reflection.Emit; 30 | 31 | 32 | // TODO: Remove this - I don't believe it is used. 33 | 34 | // First attempt at support for Excel Services. 35 | 36 | // The information I use is from http://blogs.msdn.com/cumgranosalis/default.aspx 37 | // The Excel Services managed Udf model allows classes to be marked with 38 | // Microsoft.Office.Excel.Server.Udf.UdfClass 39 | // and some of the class's methods to be marked as Udfs using 40 | // Microsoft.Office.Excel.Server.Udf.UdfMethod. 41 | // Previously ExcelDna supported only static methods to be exported, 42 | // and the main issue for compatibility is to decide how to handle the object 43 | // instantiation. 44 | // (This should not be confused with proper support for object references as 45 | // described by the Excel gurus. 46 | // Built-in support for this might come later to ExcelDna 47 | // but it could be currently implemented in a user library without 48 | // further built-in support, just as it would be done inside an .xll.) 49 | // In Excel Services the objects are instantiated per session, 50 | // in the client model it's not so clear what to do. 51 | // I think the ideal plan is to lazy-instantiate the objects, but this would 52 | // require the generation of stubs that handle the checking and instantiation. 53 | // So my first-pass solution is to create all the objects when the library is 54 | // first loaded, and keep them around forever. 55 | 56 | // CONSIDER: The support for instance methods actually impacts quite a lot of the XlMethodInfo story. 57 | // So the right way to add this support would be to refactor XlMethodInfo into a hierarchy 58 | // with children for functions and macros, and for instance methods vs. static methods. 59 | 60 | namespace ExcelDna.Integration 61 | { 62 | // Loads the managed assembly, finds all the methods to be exported to Excel 63 | // and build the method information. 64 | internal class AssemblyLoaderExcelServer 65 | { 66 | 67 | internal class ExcelServerInfo 68 | { 69 | public object Instance; 70 | public List Methods; 71 | } 72 | 73 | internal static void GetExcelServerInfos(Type t, object[] attribs, List excelServerInfos) 74 | { 75 | bool isUdfClass = false; 76 | foreach (object attrib in attribs) 77 | { 78 | Type attribType = attrib.GetType(); 79 | if (attribType.FullName == "Microsoft.Office.Excel.Server.Udf.UdfClassAttribute") 80 | { 81 | // Candidate for export 82 | isUdfClass = true; 83 | break; 84 | } 85 | } 86 | if (!isUdfClass) return; 87 | 88 | // Instantiate -- the class must have a parameterless constructor 89 | ConstructorInfo ci = t.GetConstructor(new Type[0]); 90 | if (ci == null) 91 | { 92 | // Bad case 93 | Debug.Print("ExcelDNA -> UdfClass: " + t.FullName + " has no parameterless constructor."); 94 | return; 95 | } 96 | 97 | try 98 | { 99 | object instance = ci.Invoke(null); 100 | ExcelServerInfo serverInfo = new ExcelServerInfo(); 101 | excelServerInfos.Add(serverInfo); 102 | serverInfo.Instance = instance; 103 | serverInfo.Methods = new List(); 104 | 105 | // Now go through all the methods, finding those with the UdfMethod attribute 106 | foreach (MethodInfo method in t.GetMethods(BindingFlags.Public | BindingFlags.Instance)) 107 | { 108 | // Simple check that this is a function 109 | if (method.ReturnType == typeof(void)) 110 | { 111 | // Bad case 112 | Debug.Print("ExcelDNA -> UdfMethod: " + method.Name + " returns void."); 113 | continue; 114 | } 115 | 116 | foreach (object attrib in method.GetCustomAttributes(false)) 117 | { 118 | // CONSIDER: Does this GetType() require that the assembly which defines 119 | // the attribute be available? 120 | Type attribType = attrib.GetType(); 121 | 122 | if (attribType.FullName == "Microsoft.Office.Excel.Server.Udf.UdfMethodAttribute") 123 | { 124 | // Candidate for export 125 | serverInfo.Methods.Add(method); 126 | } 127 | } 128 | } 129 | } 130 | catch { } 131 | } 132 | 133 | static internal void GetExcelServerMethods(List serverInfos, List methods) 134 | { 135 | 136 | // Prevent dynamic assembly if no Udf* methods 137 | if (serverInfos.Count == 0) return; 138 | 139 | // Now we build a module with 140 | AssemblyBuilder assemblyBuilder; 141 | ModuleBuilder moduleBuilder; 142 | assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( 143 | new AssemblyName("ExcelDna.ExcelServer.DynamicDelegateAssembly"/*TODO:Add assembly name to disambiguate different add-ins?*/), 144 | AssemblyBuilderAccess.Run/*AndSave*/); 145 | moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicDelegates"); 146 | TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicType"); 147 | 148 | // First pass - create all the static fields and redirection code 149 | foreach (ExcelServerInfo serverInfo in serverInfos) 150 | { 151 | string fieldName = serverInfo.Instance.GetType().Name; 152 | FieldBuilder fieldBuilder = typeBuilder.DefineField(fieldName, serverInfo.Instance.GetType(), FieldAttributes.Public | FieldAttributes.Static); 153 | foreach (MethodInfo method in serverInfo.Methods) 154 | { 155 | // Add a static method to the type that contains an instance 156 | // and a call to the instance method. 157 | ParameterInfo[] parameterInfos = method.GetParameters(); 158 | Type[] paramTypes = Array.ConvertAll(parameterInfos, delegate(ParameterInfo parameterInfo) { return parameterInfo.ParameterType; }); 159 | MethodBuilder methodBuilder = typeBuilder.DefineMethod(method.Name, 160 | MethodAttributes.Public | MethodAttributes.Static, 161 | method.ReturnType, 162 | paramTypes); 163 | 164 | // TODO: Set attributes on parameters so that custom function categories etc. will work 165 | ILGenerator wrapIL = methodBuilder.GetILGenerator(); 166 | LocalBuilder retobj = null; 167 | // Make a local to contain the return value 168 | retobj = wrapIL.DeclareLocal(method.ReturnType); 169 | 170 | wrapIL.Emit(OpCodes.Ldsfld, fieldBuilder); 171 | // push all the arguments 172 | for (byte i = 0; i < paramTypes.Length; i++) 173 | { 174 | wrapIL.Emit(OpCodes.Ldarg_S, i); 175 | } 176 | // Call the real method 177 | wrapIL.EmitCall(OpCodes.Call, method, null); 178 | //// Store the return value into the local variable 179 | wrapIL.Emit(OpCodes.Stloc_S, retobj); 180 | //// Push the return value 181 | wrapIL.Emit(OpCodes.Ldloc_S, retobj); 182 | wrapIL.Emit(OpCodes.Ret); 183 | 184 | } 185 | } 186 | 187 | // Bake the type 188 | Type wrapperType = typeBuilder.CreateType(); 189 | 190 | // Second pass - set field values and create delegates 191 | foreach (ExcelServerInfo serverInfo in serverInfos) 192 | { 193 | string typeName = serverInfo.Instance.GetType().Name; 194 | FieldInfo field = wrapperType.GetField(typeName); 195 | field.SetValue(null, serverInfo.Instance); 196 | foreach (MethodInfo method in serverInfo.Methods) 197 | { 198 | MethodInfo wrapperMethod = wrapperType.GetMethod(method.Name); 199 | methods.Add(wrapperMethod); 200 | } 201 | } 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/AssemblyReference.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using System.IO; 28 | using System.Reflection; 29 | 30 | namespace ExcelDna.Integration 31 | { 32 | // This class is used for the dynamic assembly references. 33 | // It manages the collection of assemblies that are referenced by each project, 34 | // and registers with the AppDomain to assist in assembly resolution. 35 | // I want it to work as I expected it to initially. 36 | // This means that the assembly found at the full path provided in the references section 37 | // when the dynamic assembly was compiled, 38 | // will be resolved as an assembly when the dynamic code runs. 39 | // For now, it seems I cannot intercept the assembly resolution to prevent it from 40 | // working in the usual way, but I intercept failures and fix up there. 41 | 42 | // TODO: This class might grow to also manage COM and DnaProject references. 43 | // CONSIDER: Fold into Reference class? 44 | 45 | public class AssemblyReference 46 | { 47 | public string Path; 48 | public Assembly Assembly; 49 | 50 | static Dictionary AssemblyReferences = new Dictionary(); 51 | static AssemblyReference() 52 | { 53 | AppDomain.CurrentDomain.AssemblyResolve += Resolve; 54 | } 55 | 56 | public static void AddAssembly(string path) 57 | { 58 | if (path != null && !AssemblyReferences.ContainsKey(path) && File.Exists(path)) 59 | { 60 | AssemblyReference ar = new AssemblyReference(); 61 | ar.Path = path; 62 | ar.Assembly = Assembly.LoadFrom(path); 63 | AssemblyReferences.Add(path, ar); 64 | } 65 | } 66 | 67 | // Way to sort out the assembly resolve to an assembly that was referenced 68 | // but is not now accessible. 69 | // CONSIDER: How to do this better? 70 | internal static Assembly Resolve(object sender, ResolveEventArgs args) 71 | { 72 | foreach (AssemblyReference ar in AssemblyReferences.Values) 73 | { 74 | if (ar.Assembly.FullName == args.Name) 75 | return ar.Assembly; 76 | } 77 | return null; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/CreateDnaLibrarySerializer.bat: -------------------------------------------------------------------------------- 1 | sgen /a:bin\Debug\exceldna.integration.dll /t:ExcelDna.Integration.DnaLibrary /k /f /out:. 2 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelAsyncHandle.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Diagnostics; 27 | using ExcelDna.Integration.Rtd; 28 | 29 | namespace ExcelDna.Integration 30 | { 31 | // NOTE: The types and methods in this file are called via reflection from ExcelDna.Loader - IntegrationMarshalHelpers.cs 32 | 33 | // CONSIDER: Should this rather be an interface? Does it matter? 34 | public abstract class ExcelAsyncHandle 35 | { 36 | public abstract bool SetResult(object result); 37 | public abstract bool SetException(Exception exception); 38 | } 39 | 40 | internal class ExcelAsyncHandleNative : ExcelAsyncHandle 41 | { 42 | // NOTE: This field is read by reflection from ExcelDna.Loader.IntegrationMarshalHelpers 43 | readonly IntPtr _handle; 44 | 45 | // NOTE: This constructor is accessed by reflection from ExcelDna.Loader.IntegrationMarshalHelpers 46 | ExcelAsyncHandleNative(IntPtr handle) 47 | { 48 | _handle = handle; 49 | } 50 | 51 | public override bool SetResult(object result) 52 | { 53 | // Typically called from a completely independent thread, e.g. a threadpool worker, 54 | // so any exception here would crash Excel. 55 | object unusedResult; 56 | XlCall.XlReturn callReturn = XlCall.TryExcel(XlCall.xlAsyncReturn, out unusedResult, this, result); 57 | if (callReturn == XlCall.XlReturn.XlReturnSuccess) 58 | { 59 | // The normal case - value has been accepted 60 | return true; 61 | } 62 | 63 | if (callReturn == XlCall.XlReturn.XlReturnInvAsynchronousContext) 64 | { 65 | // This is expected sometimes (e.g. calculation was cancelled) 66 | // Excel will show #VALUE 67 | Debug.WriteLine("Warning: InvalidAsyncContext returned from xlAsyncReturn"); 68 | return false; 69 | } 70 | 71 | // This is never unexpected 72 | Debug.WriteLine("Error: Unexpected error from xlAsyncReturn"); 73 | return false; 74 | } 75 | 76 | // Calls the Excel-DNA UnhandledExceptionHandler (which by default returns #VALUE to Excel). 77 | public override bool SetException(Exception exception) 78 | { 79 | object result = ExcelIntegration.HandleUnhandledException(exception); 80 | return SetResult(result); 81 | } 82 | 83 | // We could do something like this: 84 | //public static bool SetResults(object[] asyncHandles, object[] results) 85 | //{ 86 | //XlCall.XlReturn callReturn = XlCall.TryExcel(XlCall.xlAsyncReturn, out unusedResult, asyncHandles, results); 87 | //} 88 | } 89 | 90 | internal class ExcelAsyncHandleObservable : ExcelAsyncHandle, IExcelObservable 91 | { 92 | bool _hasResult; 93 | object _result; 94 | Exception _exception; 95 | IExcelObserver _observer; 96 | readonly object _observerLock = new object(); 97 | 98 | public override bool SetResult(object result) 99 | { 100 | lock (_observerLock) 101 | { 102 | if (_hasResult) throw new InvalidOperationException("ExcelAsyncHandle Result can be set only once."); 103 | 104 | _hasResult = true; 105 | _result = result; 106 | 107 | if (_observer != null) 108 | { 109 | _observer.OnNext(result); 110 | _observer.OnCompleted(); 111 | } 112 | return true; 113 | } 114 | } 115 | 116 | public override bool SetException(Exception exception) 117 | { 118 | lock (_observerLock) 119 | { 120 | if (_hasResult) throw new InvalidOperationException("ExcelAsyncHandle Result can be set only once."); 121 | 122 | _hasResult = true; 123 | _exception = exception; 124 | 125 | if (_observer != null) 126 | { 127 | _observer.OnError(exception); 128 | } 129 | return true; 130 | } 131 | } 132 | 133 | public IDisposable Subscribe(IExcelObserver observer) 134 | { 135 | lock (_observerLock) 136 | { 137 | if (_observer != null) throw new InvalidOperationException("Only single Subscription allowed."); 138 | _observer = observer; 139 | 140 | if (_hasResult) 141 | { 142 | if (_exception != null) 143 | { 144 | _observer.OnError(_exception); 145 | } 146 | else 147 | { 148 | _observer.OnNext(_result); 149 | _observer.OnCompleted(); 150 | } 151 | } 152 | } 153 | 154 | return DummyDisposable.Instance; 155 | } 156 | 157 | class DummyDisposable : IDisposable 158 | { 159 | public static readonly DummyDisposable Instance = new DummyDisposable(); 160 | 161 | private DummyDisposable() 162 | { 163 | } 164 | 165 | public void Dispose() 166 | { 167 | } 168 | } 169 | 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelAsyncUtil.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Diagnostics; 27 | using System.Threading; 28 | using ExcelDna.Integration.Rtd; 29 | 30 | namespace ExcelDna.Integration 31 | { 32 | // Introduction to Rx: http://www.introtorx.com/ 33 | 34 | // Task.ToObservable: http://blogs.msdn.com/b/pfxteam/archive/2010/04/04/9990349.aspx 35 | 36 | // Pattern for making an Observable: http://msdn.microsoft.com/en-us/library/dd990377.aspx 37 | // Task.ToObservable: http://blogs.msdn.com/b/pfxteam/archive/2010/04/04/9990349.aspx 38 | 39 | // Action and Func are not defined in .NET 2.0 40 | public delegate void ExcelAction(); 41 | public delegate object ExcelFunc(); 42 | public delegate void ExcelFuncAsyncHandle(ExcelAsyncHandle handle); 43 | public delegate IExcelObservable ExcelObservableSource(); 44 | 45 | // The next two interfaces would be regular System.IObservable if we could target .NET 4. 46 | // TODO: Make an adapter to make it easy to integrate with .NET 4. 47 | public interface IExcelObservable 48 | { 49 | IDisposable Subscribe(IExcelObserver observer); 50 | } 51 | 52 | public interface IExcelObserver 53 | { 54 | void OnCompleted(); 55 | void OnError(Exception exception); 56 | void OnNext(object value); 57 | } 58 | 59 | public static class ExcelAsyncUtil 60 | { 61 | [Obsolete("ExcelAsyncUtil.Initialize is no longer required. The call can be removed.")] 62 | public static void Initialize() {} 63 | [Obsolete("ExcelAsyncUtil.Uninitialize is no longer required. The call can be removed.")] 64 | public static void Uninitialize() {} 65 | 66 | // Async observable support 67 | // This is the most general RTD registration 68 | public static object Observe(string callerFunctionName, object callerParameters, ExcelObservableSource observableSource) 69 | { 70 | return AsyncObservableImpl.ProcessObservable(callerFunctionName, callerParameters, observableSource); 71 | } 72 | 73 | // Async function support 74 | public static object Run(string callerFunctionName, object callerParameters, ExcelFunc asyncFunc) 75 | { 76 | Debug.Print("ExcelAsyncUtil.Run - {0} : {1}", callerFunctionName, callerParameters); 77 | return AsyncObservableImpl.ProcessFunc(callerFunctionName, callerParameters, asyncFunc); 78 | } 79 | 80 | // Async function with ExcelAsyncHandle 81 | // The function will run on the main thread (like an Excel 2010+ native async function), 82 | // but can spawn a thread and return the value later. 83 | public static object Run(string callerFunctionName, object callerParameters, ExcelFuncAsyncHandle asyncFunc) 84 | { 85 | return AsyncObservableImpl.ProcessFuncAsyncHandle(callerFunctionName, callerParameters, asyncFunc); 86 | } 87 | 88 | // Async macro support 89 | public static void QueueMacro(string macroName) 90 | { 91 | QueueAsMacro(RunMacro, macroName); 92 | } 93 | 94 | public static void QueueAsMacro(ExcelAction action) 95 | { 96 | SendOrPostCallback callback = delegate { action(); }; 97 | QueueAsMacro(callback, null); 98 | } 99 | 100 | public static void QueueAsMacro(SendOrPostCallback callback, object state) 101 | { 102 | SynchronizationManager.RunMacroSynchronization.RunAsMacroAsync(callback, state); 103 | } 104 | 105 | static void RunMacro(object macroName) 106 | { 107 | XlCall.Excel(XlCall.xlcRun, macroName); 108 | } 109 | 110 | #region Async calculation events 111 | // CONSIDER: Do we need to unregister these when unloaded / reloaded? 112 | 113 | static ExcelAction _calculationCanceled = null; 114 | public static event ExcelAction CalculationCanceled 115 | { 116 | add 117 | { 118 | if (_calculationCanceled != null) 119 | { 120 | // We've set it up already 121 | // just add the delegate to the event 122 | _calculationCanceled += value; 123 | } 124 | else 125 | { 126 | // First time - register event handler 127 | _calculationCanceled = value; 128 | double result = (double)XlCall.Excel(XlCall.xlEventRegister, "CalculationCanceled", XlCall.xleventCalculationCanceled); 129 | if (result == 0) 130 | { 131 | // CONSIDER: Is there a better way to handle this unexpected error? 132 | throw new XlCallException(XlCall.XlReturn.XlReturnFailed); 133 | } 134 | } 135 | } 136 | remove 137 | { 138 | _calculationCanceled -= value; 139 | if (_calculationCanceled == null) 140 | { 141 | XlCall.Excel(XlCall.xlEventRegister, null, XlCall.xleventCalculationCanceled); 142 | } 143 | } 144 | } 145 | 146 | internal static void OnCalculationCanceled() 147 | { 148 | if (_calculationCanceled != null) _calculationCanceled(); 149 | } 150 | 151 | static ExcelAction _calculationEnded = null; 152 | public static event ExcelAction CalculationEnded 153 | { 154 | add 155 | { 156 | if (_calculationEnded != null) 157 | { 158 | // We've set it up already 159 | // just add the delegate to the event 160 | _calculationEnded += value; 161 | } 162 | else 163 | { 164 | // First time - register event handler 165 | _calculationEnded = value; 166 | double result = (double)XlCall.Excel(XlCall.xlEventRegister, "CalculationEnded", XlCall.xleventCalculationEnded); 167 | if (result == 0) 168 | { 169 | // CONSIDER: Is there a better way to handle this unexpected error? 170 | throw new XlCallException(XlCall.XlReturn.XlReturnFailed); 171 | } 172 | } 173 | } 174 | remove 175 | { 176 | _calculationEnded -= value; 177 | if (_calculationEnded == null) 178 | { 179 | XlCall.Excel(XlCall.xlEventRegister, null, XlCall.xleventCalculationEnded); 180 | } 181 | } 182 | } 183 | 184 | internal static void OnCalculationEnded() 185 | { 186 | if (_calculationEnded != null) _calculationEnded(); 187 | } 188 | #endregion 189 | } 190 | } -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelAttributes.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | 27 | namespace ExcelDna.Integration 28 | { 29 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] 30 | public class ExcelFunctionAttribute : Attribute 31 | { 32 | public string Name = null; 33 | public string Description = null; 34 | public string Category = null; 35 | public string HelpTopic = null; 36 | public bool IsVolatile = false; 37 | public bool IsHidden = false; 38 | public bool IsExceptionSafe = false; 39 | public bool IsMacroType = false; 40 | public bool IsThreadSafe = false; 41 | public bool IsClusterSafe = false; 42 | public bool ExplicitRegistration = false; 43 | 44 | public ExcelFunctionAttribute() 45 | { 46 | } 47 | 48 | public ExcelFunctionAttribute(string description) 49 | { 50 | Description = description; 51 | } 52 | } 53 | 54 | [AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)] 55 | public class ExcelArgumentAttribute : Attribute 56 | { 57 | public string Name = null; 58 | public string Description = null; 59 | public bool AllowReference = false; 60 | 61 | public ExcelArgumentAttribute() 62 | { 63 | } 64 | 65 | public ExcelArgumentAttribute(string description) 66 | { 67 | Description = description; 68 | } 69 | } 70 | 71 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] 72 | public class ExcelCommandAttribute : Attribute 73 | { 74 | public string Name = null; 75 | public string Description = null; 76 | public string HelpTopic = null; 77 | public string ShortCut = null; 78 | public string MenuName = null; 79 | public string MenuText = null; 80 | public bool IsExceptionSafe = false; 81 | public bool ExplicitRegistration = false; 82 | 83 | [Obsolete("ExcelFunctions can be declared hidden, not ExcelCommands.")] 84 | public bool IsHidden = false; 85 | 86 | public ExcelCommandAttribute() 87 | { 88 | } 89 | 90 | public ExcelCommandAttribute(string description) 91 | { 92 | Description = description; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelComAddIn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Globalization; 5 | using System.Reflection; 6 | using System.Runtime.InteropServices; 7 | using ExcelDna.ComInterop.ComRegistration; 8 | using ExcelDna.Integration.CustomUI; 9 | using ExcelDna.Integration.Extensibility; 10 | 11 | namespace ExcelDna.Integration 12 | { 13 | [ComVisible(true)] 14 | [ClassInterface(ClassInterfaceType.AutoDispatch)] 15 | public class ExcelComAddIn : IDTExtensibility2 16 | { 17 | internal DnaLibrary DnaLibrary { get; set; } 18 | private string _progId; 19 | protected string ProgId 20 | { 21 | get { return _progId; } 22 | } 23 | 24 | internal void SetProgId(string progId) 25 | { 26 | _progId = progId; 27 | } 28 | 29 | #region IDTExtensibility2 interface 30 | public virtual void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom) 31 | { 32 | Debug.Print("ExcelComAddIn.OnConnection"); 33 | } 34 | 35 | public virtual void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom) 36 | { 37 | Debug.Print("ExcelComAddIn.OnDisconnection"); 38 | } 39 | 40 | public virtual void OnAddInsUpdate(ref Array custom) 41 | { 42 | Debug.Print("ExcelComAddIn.OnAddInsUpdate"); 43 | } 44 | 45 | public virtual void OnStartupComplete(ref Array custom) 46 | { 47 | Debug.Print("ExcelComAddIn.OnStartupComplete"); 48 | } 49 | 50 | public virtual void OnBeginShutdown(ref Array custom) 51 | { 52 | Debug.Print("ExcelComAddIn.OnBeginShutdown"); 53 | } 54 | #endregion 55 | } 56 | 57 | public static class ExcelComAddInHelper 58 | { 59 | // Com Add-ins loaded for Ribbons. 60 | static List loadedComAddIns = new List(); 61 | 62 | public static void LoadComAddIn(ExcelComAddIn addIn) 63 | { 64 | // If we are called without the addIn's DnaLibrary being set, default to the current library 65 | if (addIn.DnaLibrary == null) 66 | addIn.DnaLibrary = DnaLibrary.CurrentLibrary; 67 | 68 | Guid clsId; 69 | string progId; 70 | 71 | // If we have both an explicit Guid and an explicit ProgId, then use those, else create synthetic ProgId. 72 | object[] progIdAttrs = addIn.GetType().GetCustomAttributes(typeof(ProgIdAttribute), false); 73 | object[] guidAttrs = addIn.GetType().GetCustomAttributes(typeof(GuidAttribute), false); 74 | if (progIdAttrs.Length >= 1 && guidAttrs.Length >= 1) 75 | { 76 | // Use the attributes 77 | ProgIdAttribute progIdAtt = (ProgIdAttribute)progIdAttrs[0]; 78 | progId = progIdAtt.Value; 79 | 80 | GuidAttribute guidAtt = (GuidAttribute)guidAttrs[0]; 81 | clsId = new Guid(guidAtt.Value); 82 | } 83 | else 84 | { 85 | // Use a stable Guid derived from the Xll Path (since Excel stores load-times and other info for every COM add-in loaded in the registry) 86 | clsId = ExcelDnaUtil.XllGuid; 87 | // and make the ProgId from this Guid - max 39 chars.... 88 | progId = "Dna." + clsId.ToString("N") + "." + loadedComAddIns.Count; 89 | } 90 | addIn.SetProgId(progId); 91 | 92 | // Put together some nicer descriptions for the Add-ins dialog. 93 | string friendlyName; 94 | if (addIn is ExcelRibbon) 95 | friendlyName = addIn.DnaLibrary.Name; // + " (Ribbon Helper)"; (No more - it is displayed in the Ribbon tooltip!) 96 | else if (addIn is ExcelCustomTaskPaneAddIn) 97 | friendlyName = addIn.DnaLibrary.Name + " (Custom Task Pane Helper)"; 98 | else 99 | friendlyName = addIn.DnaLibrary.Name + " (COM Add-in Helper)"; 100 | string description = string.Format("Dynamically created COM Add-in to load custom UI for the Excel Add-in {0}, located at {1}.", addIn.DnaLibrary.Name, DnaLibrary.XllPath); 101 | 102 | 103 | Debug.Print("Getting Application object"); 104 | object app = ExcelDnaUtil.Application; 105 | Type appType = app.GetType(); 106 | Debug.Print("Got Application object: " + app.GetType().ToString()); 107 | 108 | CultureInfo ci = new CultureInfo(1033); 109 | object excelComAddIns; 110 | object comAddIn; 111 | 112 | try 113 | { 114 | using (new SingletonClassFactoryRegistration(addIn, clsId)) 115 | using (new ProgIdRegistration(progId, clsId)) 116 | using (new ComAddInRegistration(progId, friendlyName, description)) 117 | { 118 | excelComAddIns = appType.InvokeMember("COMAddIns", BindingFlags.GetProperty, null, app, null, ci); 119 | // Debug.Print("Got COMAddins object: " + excelComAddIns.GetType().ToString()); 120 | appType.InvokeMember("Update", BindingFlags.InvokeMethod, null, excelComAddIns, null, ci); 121 | // Debug.Print("Updated COMAddins object with AddIn registered"); 122 | comAddIn = excelComAddIns.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, excelComAddIns, new object[] { progId }, ci); 123 | // Debug.Print("Got the COMAddin object: " + comAddIn.GetType().ToString()); 124 | 125 | // At this point Excel knows how to load our add-in by CLSID, so we could clean up the 126 | // registry aggressively, before the actual (dangerous?) loading starts. 127 | // But this seems to lead to some distress - Excel has some assertion checked when 128 | // it updates the LoadBehavior after a successful load.... 129 | comAddIn.GetType().InvokeMember("Connect", BindingFlags.SetProperty, null, comAddIn, new object[] { true }, ci); 130 | // Debug.Print("COMAddin is loaded."); 131 | loadedComAddIns.Add(comAddIn); 132 | } 133 | } 134 | catch (UnauthorizedAccessException secex) 135 | { 136 | Logging.LogDisplay.WriteLine("The Ribbon/COM Add-in helper required by add-in {0} could not be registered.\r\nThis may be due to restricted permissions on the user's HKCU\\Software\\Classes key.\r\nError message: {1}", DnaLibrary.CurrentLibrary.Name, secex.Message); 137 | Debug.Print("LoadComAddIn exception: " + secex.ToString()); 138 | } 139 | catch (Exception ex) 140 | { 141 | Logging.LogDisplay.WriteLine("The Ribbon/COM Add-in helper required by add-in {0} could not be registered.\r\nThis is an unexpected error.\r\nError message: {1}", DnaLibrary.CurrentLibrary.Name, ex.Message); 142 | Debug.Print("LoadComAddIn exception: " + ex.ToString()); 143 | } 144 | } 145 | 146 | internal static void UnloadComAddIns() 147 | { 148 | CultureInfo ci = new CultureInfo(1033); 149 | foreach (object comAddIn in loadedComAddIns) 150 | { 151 | comAddIn.GetType().InvokeMember("Connect", System.Reflection.BindingFlags.SetProperty, null, comAddIn, new object[] { false }, ci); 152 | Debug.Print("COMAddin is unloaded."); 153 | } 154 | } 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelCustomTaskPane.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using System.Runtime.InteropServices; 28 | using ExcelDna.ComInterop.ComRegistration; 29 | 30 | namespace ExcelDna.Integration.CustomUI 31 | { 32 | public static class CustomTaskPaneFactory 33 | { 34 | private static ExcelCustomTaskPaneAddIn _addin; 35 | 36 | // We keep a list of CustomTaksPanes, so that we can clean up when the add-in is removed or reopened. 37 | // But we don't want to artificially extend the lifetime of CTPs if the add-in is not keeping a reference. 38 | // So we use WeakReferences to not interfere with lifetime, but have a chance to clean up for live ones. 39 | private static readonly List _customTaskPanes = new List(); 40 | 41 | public static CustomTaskPane CreateCustomTaskPane(Type userControlType, string title) 42 | { 43 | return CreateCustomTaskPane(userControlType, title, Type.Missing); 44 | } 45 | 46 | public static CustomTaskPane CreateCustomTaskPane(Type userControlType, string title, object parent) 47 | { 48 | //if (!typeof(System.Windows.Forms.UserControl).IsAssignableFrom(userControlType)) 49 | //{ 50 | // throw new ArgumentException("userControlType for Custom Task Pane must be derive from type System.Windows.Forms.UserControl"); 51 | //} 52 | 53 | // I could use the ProgId and ClsId of the UserControl type here. 54 | // But then the registration has to be persistent or coordinated, which I dislike. 55 | // It's already a problem for the RTD servers. 56 | // Users that want persistent and consistent names, can sort out registration themselves, or use the ExcelComClass support. 57 | // Then the CTP is created through the CreateCustomTaskPane("My.ProgId",...) overloads. 58 | 59 | // So when passed the type, I always synthesize a progid. 60 | // We pick a new Guid as ClassId for this add-in... 61 | Guid clsId = Guid.NewGuid(); 62 | // ...and make the ProgId from this Guid - max 39 chars. 63 | string progId = "CtpSrv." + clsId.ToString("N"); 64 | 65 | // Instantiate and then register UserControl 66 | // For some reason, there is a problem loading the user control when running under an elevated UAC token. 67 | // So we use the form of the registration which tries to first register for the machine, 68 | // then fall back to the user hive if that fails. 69 | 70 | try 71 | { 72 | object userControl = Activator.CreateInstance(userControlType); 73 | using (new SingletonClassFactoryRegistration(userControl, clsId)) 74 | using (new ProgIdUacRegistration(progId, clsId)) 75 | using (new ClsIdUacRegistration(clsId, progId)) 76 | { 77 | return CreateCustomTaskPane(progId, title, parent); 78 | } 79 | } 80 | catch (UnauthorizedAccessException secex) 81 | { 82 | Logging.LogDisplay.WriteLine("The CTP Helper required by add-in {0} could not be registered.\r\nThis may be due to restricted permissions on the user's HKCU\\Software\\Classes key.\r\nError message: {1}", 83 | DnaLibrary.CurrentLibrary.Name, secex.Message); 84 | return null; 85 | } 86 | } 87 | 88 | // UserControl as already registered. Just create via factory and add-in. 89 | public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title) 90 | { 91 | return CreateCustomTaskPane(controlProgId, title, Type.Missing); 92 | } 93 | 94 | public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title, object parent) 95 | { 96 | ICTPFactory factory = GetCTPFactory(); 97 | CustomTaskPane newCTP = factory.CreateCTP(controlProgId, title, parent); 98 | _customTaskPanes.Add(new WeakReference(newCTP)); // TODO: Only removed when add-in is unloaded...??? 99 | return newCTP; 100 | } 101 | 102 | private static ICTPFactory GetCTPFactory() 103 | { 104 | if (_addin == null) 105 | { 106 | // Register and create addin 107 | _addin = new ExcelCustomTaskPaneAddIn { DnaLibrary = DnaLibrary.CurrentLibrary }; 108 | ExcelComAddInHelper.LoadComAddIn(_addin); 109 | } 110 | return _addin.Factory; 111 | } 112 | 113 | internal static void UnloadCustomTaskPanes() 114 | { 115 | foreach (WeakReference ctpWr in _customTaskPanes) 116 | { 117 | CustomTaskPane ctp = ctpWr.Target as CustomTaskPane; 118 | if (ctp != null) 119 | { 120 | ctp.Delete(); 121 | Marshal.FinalReleaseComObject(ctp); 122 | } 123 | } 124 | _customTaskPanes.Clear(); 125 | } 126 | 127 | internal static void DetachAddIn() 128 | { 129 | _addin = null; 130 | } 131 | } 132 | 133 | internal class ExcelCustomTaskPaneAddIn : ExcelComAddIn, ICustomTaskPaneConsumer 134 | { 135 | public ICTPFactory Factory; 136 | 137 | // For CustomTaskPane stuff 138 | // TODO: ActiveX -> WPF without Windows.Forms....? 139 | public void CTPFactoryAvailable(ICTPFactory CTPFactoryInst) 140 | { 141 | Factory = CTPFactoryInst; 142 | } 143 | 144 | public override void OnDisconnection(Extensibility.ext_DisconnectMode RemoveMode, ref Array custom) 145 | { 146 | // Unloading custom task panes prevents the crash on Excel 2010 64-bit. 147 | CustomTaskPaneFactory.UnloadCustomTaskPanes(); 148 | CustomTaskPaneFactory.DetachAddIn(); 149 | if (Factory != null) 150 | { 151 | Marshal.ReleaseComObject(Factory); 152 | Factory = null; 153 | } 154 | base.OnDisconnection(RemoveMode, ref custom); 155 | } 156 | } 157 | 158 | 159 | } 160 | 161 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelDna.Integration.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9} 9 | Library 10 | Properties 11 | ExcelDna.Integration 12 | ExcelDna.Integration 13 | v2.0 14 | 512 15 | OnOutputUpdated 16 | 17 | 18 | 3.5 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | DEBUG;TRACE 28 | prompt 29 | 4 30 | false 31 | Off 32 | default 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | false 42 | Off 43 | default 44 | 45 | 46 | true 47 | bin\x86\Debug\ 48 | DEBUG;TRACE 49 | full 50 | x86 51 | Off 52 | default 53 | prompt 54 | MinimumRecommendedRules.ruleset 55 | 56 | 57 | bin\x86\Release\ 58 | TRACE 59 | true 60 | pdbonly 61 | x86 62 | Off 63 | default 64 | prompt 65 | MinimumRecommendedRules.ruleset 66 | 67 | 68 | true 69 | bin\x64\Debug\ 70 | DEBUG;TRACE 71 | full 72 | x64 73 | Off 74 | default 75 | prompt 76 | MinimumRecommendedRules.ruleset 77 | 78 | 79 | bin\x64\Release\ 80 | TRACE 81 | true 82 | pdbonly 83 | x64 84 | Off 85 | default 86 | prompt 87 | MinimumRecommendedRules.ruleset 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | Form 125 | 126 | 127 | LogDisplay.cs 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | LogDisplay.cs 142 | Designer 143 | 144 | 145 | 146 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelDna.Integration.vs2008.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9} 9 | Library 10 | Properties 11 | ExcelDna.Integration 12 | ExcelDna.Integration 13 | v2.0 14 | 512 15 | OnOutputUpdated 16 | 17 | 18 | 3.5 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | false 30 | Off 31 | 32 | 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | false 40 | Off 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | Form 70 | 71 | 72 | LogDisplay.cs 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | LogDisplay.cs 86 | Designer 87 | 88 | 89 | 90 | 97 | 98 | copy $(TargetPath) $(SolutionDir)ExcelDna\$(ConfigurationName)\ 99 | 100 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelError.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System.Runtime.InteropServices; 26 | 27 | namespace ExcelDna.Integration 28 | { 29 | public enum ExcelError : short 30 | { 31 | ExcelErrorNull = 0, 32 | ExcelErrorDiv0 = 7, 33 | ExcelErrorValue = 15, 34 | ExcelErrorRef = 23, 35 | ExcelErrorName = 29, 36 | ExcelErrorNum = 36, 37 | ExcelErrorNA = 42, 38 | ExcelErrorGettingData = 43 39 | } 40 | 41 | public class ExcelMissing 42 | { 43 | public static readonly ExcelMissing Value = new ExcelMissing(); 44 | 45 | private ExcelMissing() 46 | { 47 | } 48 | } 49 | 50 | public class ExcelEmpty 51 | { 52 | public static readonly ExcelEmpty Value = new ExcelEmpty(); 53 | 54 | private ExcelEmpty() 55 | { 56 | } 57 | } 58 | 59 | public static class ExcelErrorUtil 60 | { 61 | public static object ToComError(ExcelError excelError) 62 | { 63 | // From this post: http://groups.google.com/group/exceldna/browse_frm/thread/67a9a6c49e0b49b3 64 | int code; 65 | switch (excelError) 66 | { 67 | case ExcelError.ExcelErrorNull: 68 | code = -2146826288; 69 | break; 70 | case ExcelError.ExcelErrorDiv0: 71 | code = -2146826281; 72 | break; 73 | case ExcelError.ExcelErrorRef: 74 | code = -2146826265; 75 | break; 76 | case ExcelError.ExcelErrorName: 77 | code = -2146826259; 78 | break; 79 | case ExcelError.ExcelErrorNum: 80 | code = -2146826252; 81 | break; 82 | case ExcelError.ExcelErrorNA: 83 | code = -2146826246; 84 | break; 85 | case ExcelError.ExcelErrorGettingData: 86 | case ExcelError.ExcelErrorValue: 87 | default: 88 | code = -2146826273; 89 | break; 90 | } 91 | return new ErrorWrapper(code); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelReference.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using System.Diagnostics; 28 | 29 | namespace ExcelDna.Integration 30 | { 31 | // CAUTION: The ExcelReference class is also called via reflection by the ExcelDna.Loader marshaler. 32 | public class ExcelReference 33 | { 34 | class ExcelRectangle 35 | { 36 | public readonly int RowFirst; 37 | public readonly int RowLast; 38 | public readonly int ColumnFirst; 39 | public readonly int ColumnLast; 40 | 41 | internal ExcelRectangle(int rowFirst, int rowLast, int columnFirst, int columnLast) 42 | { 43 | // CONSIDER: Throw or truncate for errors 44 | RowFirst = GetInRange(rowFirst, 0, ExcelDnaUtil.ExcelLimits.MaxRows - 1); 45 | RowLast = GetInRange(rowLast, 0, ExcelDnaUtil.ExcelLimits.MaxRows - 1); 46 | ColumnFirst = GetInRange(columnFirst, 0, ExcelDnaUtil.ExcelLimits.MaxColumns - 1); 47 | ColumnLast = GetInRange(columnLast, 0, ExcelDnaUtil.ExcelLimits.MaxColumns - 1); 48 | 49 | // CONSIDER: Swap or truncate rect ?? 50 | //if (RowLast < RowFirst) RowLast = RowFirst; 51 | //if (ColumnLast < ColumnFirst) ColumnLast = RowFirst; 52 | } 53 | 54 | private int GetInRange(int value, int min, int max) 55 | { 56 | Debug.Assert(min <= max); 57 | if (value < min) return min; 58 | if (value > max) return max; 59 | return value; 60 | } 61 | 62 | public override bool Equals(object obj) 63 | { 64 | if (ReferenceEquals(null, obj)) return false; 65 | if (ReferenceEquals(this, obj)) return true; 66 | if (obj.GetType() != typeof (ExcelRectangle)) return false; 67 | return Equals((ExcelRectangle) obj); 68 | } 69 | 70 | bool Equals(ExcelRectangle other) 71 | { 72 | if (ReferenceEquals(null, other)) return false; 73 | if (ReferenceEquals(this, other)) return true; 74 | return other.RowFirst == RowFirst && other.RowLast == RowLast && other.ColumnFirst == ColumnFirst && other.ColumnLast == ColumnLast; 75 | } 76 | 77 | public override int GetHashCode() 78 | { 79 | unchecked 80 | { 81 | int result = RowFirst; 82 | result = (result*397) ^ RowLast; 83 | result = (result*397) ^ ColumnFirst; 84 | result = (result*397) ^ ColumnLast; 85 | return result; 86 | } 87 | } 88 | } 89 | 90 | // CONSIDER: Rather use a derived class so that we can implement Equals properly. 91 | // The implementation as a List here is actually hidden. 92 | readonly List rectangles = new List(); 93 | readonly IntPtr sheetId; 94 | 95 | public ExcelReference(int row, int column) 96 | : this(row, row, column, column) 97 | { 98 | } 99 | 100 | // DOCUMENT: If no SheetId is given, assume the Active (Front) Sheet 101 | public ExcelReference(int rowFirst, int rowLast, int columnFirst, int columnLast) : 102 | this(rowFirst, rowLast, columnFirst, columnLast, IntPtr.Zero) 103 | { 104 | try 105 | { 106 | ExcelReference r = (ExcelReference)XlCall.Excel(XlCall.xlSheetId); 107 | sheetId = r.sheetId; 108 | } 109 | catch 110 | { 111 | // CONSIDER: throw or 'default' behaviour? 112 | } 113 | } 114 | 115 | public ExcelReference(int rowFirst, int rowLast, int columnFirst, int columnLast, IntPtr sheetId) 116 | { 117 | this.sheetId = sheetId; 118 | ExcelRectangle rect = new ExcelRectangle(rowFirst, rowLast, columnFirst, columnLast); 119 | rectangles.Add(rect); 120 | } 121 | 122 | // TODO: Consider how to deal with invalid sheetName. I presume xlSheetId will fail. 123 | // Perhaps throw a custom exception...? 124 | public ExcelReference(int rowFirst, int rowLast, int columnFirst, int columnLast, string sheetName) 125 | { 126 | ExcelReference sheetRef = (ExcelReference)XlCall.Excel(XlCall.xlSheetId, sheetName); 127 | this.sheetId = sheetRef.SheetId; 128 | ExcelRectangle rect = new ExcelRectangle(rowFirst, rowLast, columnFirst, columnLast); 129 | rectangles.Add(rect); 130 | } 131 | 132 | // THROWS: OverFlowException if the arguments exceed the allowed size 133 | // or if the number of Inner References exceeds 65000 134 | public void AddReference(int rowFirst, int rowLast, int columnFirst, int columnLast) 135 | { 136 | if (rectangles.Count < ushort.MaxValue) 137 | rectangles.Add(new ExcelRectangle(rowFirst, rowLast, columnFirst, columnLast)); 138 | else 139 | throw new OverflowException("Maximum number of references exceeded"); 140 | } 141 | 142 | public int RowFirst 143 | { 144 | get { return rectangles[0].RowFirst; } 145 | } 146 | 147 | public int RowLast 148 | { 149 | get { return rectangles[0].RowLast; } 150 | } 151 | 152 | public int ColumnFirst 153 | { 154 | get { return rectangles[0].ColumnFirst; } 155 | } 156 | 157 | public int ColumnLast 158 | { 159 | get { return rectangles[0].ColumnLast; } 160 | } 161 | 162 | public IntPtr SheetId 163 | { 164 | get { return sheetId; } 165 | } 166 | 167 | public List InnerReferences 168 | { 169 | get 170 | { 171 | List inner = new List(); 172 | foreach (ExcelRectangle rect in rectangles) 173 | { 174 | inner.Add(new ExcelReference(rect.RowFirst, rect.RowLast, 175 | rect.ColumnFirst, rect.ColumnLast, sheetId)); 176 | } 177 | return inner; 178 | } 179 | } 180 | 181 | public object GetValue() 182 | { 183 | return XlCall.Excel(XlCall.xlCoerce, this); 184 | } 185 | 186 | // DOCUMENT: Strange behaviour with SetValue... 187 | public bool SetValue(object value) 188 | { 189 | return (bool)XlCall.Excel(XlCall.xlSet, this, value); 190 | } 191 | 192 | // CAUTION: These 'private' functions are called via reflection by the ExcelDna.Loader marshaler 193 | // Returns arrays containing all the inner rectangles (including the one we pretend is outside). 194 | private int[][] GetRectangles() 195 | { 196 | int[][] intRects = new int[rectangles.Count][]; 197 | for (int i = 0; i < rectangles.Count; i++) 198 | { 199 | ExcelRectangle rect = rectangles[i]; 200 | intRects[i] = new int[] {rect.RowFirst, rect.RowLast, 201 | rect.ColumnFirst, rect.ColumnLast}; 202 | } 203 | return intRects; 204 | } 205 | 206 | private int GetRectangleCount() 207 | { 208 | return rectangles.Count; 209 | } 210 | 211 | // Structural equality implementation 212 | public override bool Equals(object obj) 213 | { 214 | if (ReferenceEquals(null, obj)) return false; 215 | if (ReferenceEquals(this, obj)) return true; 216 | if (obj.GetType() != typeof (ExcelReference)) return false; 217 | return Equals((ExcelReference) obj); 218 | } 219 | 220 | bool Equals(ExcelReference other) 221 | { 222 | if (ReferenceEquals(null, other)) return false; 223 | if (ReferenceEquals(this, other)) return true; 224 | // Implement equality check based on contents. 225 | // CONSIDER: Implement in class derived from List. 226 | if (rectangles.Count != other.rectangles.Count) return false; 227 | for (int i = 0; i < rectangles.Count; i++) 228 | { 229 | if (!Equals(rectangles[i], other.rectangles[i])) return false; 230 | } 231 | return other.sheetId.Equals(sheetId); 232 | } 233 | 234 | // We need to take some care with the Hash Code here, since we use the ExcelReference with structural comparison 235 | // in some Dictionaries. 236 | public override int GetHashCode() 237 | { 238 | // One of the ideas from http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode 239 | const int b = 378551; 240 | int a = 63689; 241 | int hash = 0; 242 | 243 | unchecked 244 | { 245 | for (int i = 0; i < rectangles.Count; i++) 246 | { 247 | if (rectangles[i] != null) 248 | { 249 | hash = hash * a + rectangles[i].GetHashCode(); 250 | a = a * b; 251 | } 252 | } 253 | hash *= 397; 254 | } 255 | return hash ^ sheetId.GetHashCode(); 256 | } 257 | 258 | public override string ToString() 259 | { 260 | return string.Format("({0},{1} : {2},{3}) - {4}", RowFirst, ColumnFirst, RowLast, ColumnLast, SheetId); 261 | } 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExcelRibbon.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Globalization; 5 | using System.Reflection; 6 | using System.Runtime.InteropServices; 7 | using System.Xml; 8 | using CLSID = System.Guid; 9 | 10 | namespace ExcelDna.Integration.CustomUI 11 | { 12 | [ComVisible(true)] 13 | [ClassInterface(ClassInterfaceType.AutoDispatch)] 14 | public class ExcelRibbon : ExcelComAddIn, IRibbonExtensibility //, ICustomTaskPaneConsumer 15 | { 16 | public const string NamespaceCustomUI2010 = @"http://schemas.microsoft.com/office/2009/07/customui"; 17 | public const string NamespaceCustomUI2007 = @"http://schemas.microsoft.com/office/2006/01/customui"; 18 | 19 | public virtual string GetCustomUI(string RibbonID) 20 | { 21 | if (RibbonID != "Microsoft.Excel.Workbook") 22 | { 23 | Debug.Print("ExcelRibbon.GetCustomUI - Invalid RibbonID for Excel. RibbonID: {0}", RibbonID); 24 | return null; 25 | } 26 | 27 | // Default behaviour for GetCustomUI is to look in DnaLibrary. 28 | // We return a CustomUI based on the version of Excel, as follows: 29 | // If Excel12, look for a CustomUI with namespace... If not found, return nothing 30 | // If Excel14 or bigger look for CustomUI with namespace ... If not found, look for ... else return nothing. 31 | // (not sure how to future-proof...) 32 | 33 | Dictionary customUIs = new Dictionary(); 34 | foreach (XmlNode customUI in this.DnaLibrary.CustomUIs) 35 | { 36 | customUIs[customUI.NamespaceURI] = customUI.OuterXml; 37 | } 38 | 39 | if (ExcelDnaUtil.ExcelVersion >= 14.0) 40 | { 41 | if (customUIs.ContainsKey(NamespaceCustomUI2010)) 42 | { 43 | return customUIs[NamespaceCustomUI2010]; 44 | } 45 | if (customUIs.ContainsKey(NamespaceCustomUI2007)) 46 | { 47 | return customUIs[NamespaceCustomUI2007]; 48 | } 49 | return null; 50 | } 51 | if (ExcelDnaUtil.ExcelVersion >= 12.0) 52 | { 53 | if (customUIs.ContainsKey(NamespaceCustomUI2007)) 54 | { 55 | return customUIs[NamespaceCustomUI2007]; 56 | } 57 | return null; 58 | } 59 | throw new InvalidOperationException("Not expected to provide CustomUI string for Excel version < 12.0"); 60 | } 61 | 62 | // LoadImage helper - to use need to mark loadImage='LoadImage' in the xml. 63 | // 1. An IPictureDisp 64 | // 2. A System.Drawing.Bitmap 65 | // 3. A string containing an imageMso identifier 66 | // Our default implementation ... 67 | public virtual object LoadImage(string imageId) 68 | { 69 | // Default implementation ... 70 | return DnaLibrary.GetImage(imageId); 71 | } 72 | 73 | // RunTagMacro helper function 74 | public virtual void RunTagMacro(IRibbonControl control) 75 | { 76 | if (!string.IsNullOrEmpty(control.Tag)) 77 | { 78 | // CONSIDER: Is this a danger for shutting down - surely not...? 79 | object app = ExcelDnaUtil.Application; 80 | app.GetType().InvokeMember("Run", BindingFlags.InvokeMethod, null, app, new object[] { control.Tag }, new CultureInfo(1033)); 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExportedAssembly.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace ExcelDna.Integration 4 | { 5 | internal class ExportedAssembly 6 | { 7 | internal Assembly Assembly; 8 | internal bool ExplicitExports; 9 | internal bool ExplicitRegistration; 10 | internal bool ComServer; 11 | internal bool IsDynamic; 12 | internal string TypeLibPath; 13 | internal DnaLibrary ParentDnaLibrary; 14 | 15 | internal ExportedAssembly(Assembly assembly, bool explicitExports, bool explicitRegistration, bool comServer, bool isDynamic, string typeLibPath, DnaLibrary parentDnaLibrary) 16 | { 17 | this.Assembly = assembly; 18 | this.ExplicitExports = explicitExports; 19 | this.ExplicitRegistration = explicitRegistration; 20 | this.ComServer = comServer; 21 | this.IsDynamic = isDynamic; 22 | this.TypeLibPath = typeLibPath; 23 | this.ParentDnaLibrary = parentDnaLibrary; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/ExternalLibrary.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using System.IO; 28 | using System.Reflection; 29 | using System.Xml.Serialization; 30 | using ExcelDna.Logging; 31 | 32 | namespace ExcelDna.Integration 33 | { 34 | // TODO: Allow Com References (via TlbImp?)/Exported Libraries 35 | // DOCUMENT When loading ExternalLibraries, we check first the path given in the Path attribute: 36 | // if there is no such file, we try to find a file with the right name in the same 37 | // directory as the .xll. 38 | // We load files with .dna extension as Dna Libraries 39 | 40 | [Serializable] 41 | [XmlType(AnonymousType = true)] 42 | public class ExternalLibrary 43 | { 44 | private string _Path; 45 | [XmlAttribute] 46 | public string Path 47 | { 48 | get { return _Path; } 49 | set { _Path = value; } 50 | } 51 | 52 | private string _TypeLibPath; 53 | [XmlAttribute] 54 | public string TypeLibPath 55 | { 56 | get { return _TypeLibPath; } 57 | set { _TypeLibPath = value; } 58 | } 59 | 60 | private bool _ComServer; 61 | [XmlAttribute] 62 | public bool ComServer 63 | { 64 | get { return _ComServer; } 65 | set { _ComServer = value; } 66 | } 67 | 68 | private bool _Pack = false; 69 | [XmlAttribute] 70 | public bool Pack 71 | { 72 | get { return _Pack; } 73 | set { _Pack = value; } 74 | } 75 | 76 | private bool _LoadFromBytes = false; 77 | [XmlAttribute] 78 | public bool LoadFromBytes 79 | { 80 | get { return _LoadFromBytes; } 81 | set { _LoadFromBytes = value; } 82 | } 83 | 84 | private bool _ExplicitExports = false; 85 | [XmlAttribute] 86 | public bool ExplicitExports 87 | { 88 | get { return _ExplicitExports; } 89 | set { _ExplicitExports = value; } 90 | } 91 | 92 | private bool _ExplicitRegistration = false; 93 | [XmlAttribute] 94 | public bool ExplicitRegistration 95 | { 96 | get { return _ExplicitRegistration; } 97 | set { _ExplicitRegistration = value; } 98 | } 99 | 100 | internal List GetAssemblies(string pathResolveRoot, DnaLibrary dnaLibrary) 101 | { 102 | List list = new List(); 103 | 104 | try 105 | { 106 | string realPath = Path; 107 | if (Path.StartsWith("packed:")) 108 | { 109 | // The ExternalLibrary is packed. 110 | // We'll have to load it from resources. 111 | string resourceName = Path.Substring(7); 112 | if (Path.EndsWith(".DNA", StringComparison.OrdinalIgnoreCase)) 113 | { 114 | byte[] dnaContent = ExcelIntegration.GetDnaFileBytes(resourceName); 115 | DnaLibrary lib = DnaLibrary.LoadFrom(dnaContent, pathResolveRoot); 116 | if (lib == null) 117 | { 118 | LogDisplay.WriteLine("External library could not be registered - Path: " + Path); 119 | LogDisplay.WriteLine(" Error: Packed DnaLibrary could not be loaded."); 120 | return list; 121 | } 122 | 123 | return lib.GetAssemblies(pathResolveRoot); 124 | } 125 | else 126 | { 127 | // DOCUMENT: TypeLibPath which is a resource in a library is denoted as fileName.dll\4 128 | // For packed assemblies, we set TypeLibPath="packed:2" 129 | string typeLibPath = null; 130 | if (!string.IsNullOrEmpty(TypeLibPath) && TypeLibPath.StartsWith("packed:")) 131 | { 132 | typeLibPath = DnaLibrary.XllPath + @"\" + TypeLibPath.Substring(7); 133 | } 134 | 135 | // It would be nice to check here whether the assembly is loaded already. 136 | // But because of the name mangling in the packing we can't easily check. 137 | 138 | // So we make the following assumptions: 139 | // 1. Packed assemblies won't also be loadable from files (else they might be loaded twice) 140 | // 2. ExternalLibrary loads will happen before reference loads via AssemblyResolve. 141 | // Under these assumptions we should not have assemblies loaded more than once, 142 | // even if not checking here. 143 | byte[] rawAssembly = ExcelIntegration.GetAssemblyBytes(resourceName); 144 | Assembly assembly = Assembly.Load(rawAssembly); 145 | list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, typeLibPath, dnaLibrary)); 146 | return list; 147 | } 148 | } 149 | if (Uri.IsWellFormedUriString(Path, UriKind.Absolute)) 150 | { 151 | // Here is support for loading ExternalLibraries from http. 152 | Uri uri = new Uri(Path, UriKind.Absolute); 153 | if (uri.IsUnc) 154 | { 155 | realPath = uri.LocalPath; 156 | // Will continue to load later with the regular file load part below... 157 | } 158 | else 159 | { 160 | string scheme = uri.Scheme.ToLowerInvariant(); 161 | if (scheme != "http" && scheme != "file" && scheme != "https") 162 | { 163 | Logging.LogDisplay.WriteLine("The ExternalLibrary path {0} is not a valid Uri scheme.", Path); 164 | return list; 165 | } 166 | else 167 | { 168 | if (uri.AbsolutePath.EndsWith("dna", StringComparison.InvariantCultureIgnoreCase)) 169 | { 170 | DnaLibrary lib = DnaLibrary.LoadFrom(uri); 171 | if (lib == null) 172 | { 173 | LogDisplay.WriteLine("External library could not be registered - Path: " + Path); 174 | LogDisplay.WriteLine(" Error: DnaLibrary could not be loaded."); 175 | return list; 176 | } 177 | // CONSIDER: Should we add a resolve story for .dna files at Uris? 178 | return lib.GetAssemblies(null); // No explicit resolve path 179 | } 180 | else 181 | { 182 | // Load as a regular assembly - TypeLib not supported. 183 | Assembly assembly = Assembly.LoadFrom(Path); 184 | list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, null, dnaLibrary)); 185 | return list; 186 | } 187 | } 188 | } 189 | } 190 | // Keep trying with the current value of realPath. 191 | string resolvedPath = DnaLibrary.ResolvePath(realPath, pathResolveRoot); 192 | if (resolvedPath == null) 193 | { 194 | LogDisplay.WriteLine("External library could not be registered - Path: " + Path); 195 | LogDisplay.WriteLine(" Error: The library could not be found at this location."); 196 | return list; 197 | } 198 | if (System.IO.Path.GetExtension(resolvedPath).Equals(".DNA", StringComparison.OrdinalIgnoreCase)) 199 | { 200 | // Load as a DnaLibrary 201 | DnaLibrary lib = DnaLibrary.LoadFrom(resolvedPath); 202 | if (lib == null) 203 | { 204 | LogDisplay.WriteLine("External library could not be registered - Path: " + Path); 205 | LogDisplay.WriteLine(" Error: DnaLibrary could not be loaded."); 206 | return list; 207 | } 208 | 209 | string pathResolveRelative = System.IO.Path.GetDirectoryName(resolvedPath); 210 | return lib.GetAssemblies(pathResolveRelative); 211 | } 212 | else 213 | { 214 | Assembly assembly; 215 | // Load as a regular assembly 216 | // First check if it is already loaded (e.g. as a reference from another assembly) 217 | // DOCUMENT: Some cases might still have assemblies loaded more than once. 218 | // E.g. for an assembly that is both ExternalLibrary and references from another assembly, 219 | // having the assembly LoadFromBytes and in the file system would load it twice, 220 | // because LoadFromBytes here happens before the .NET loaders assembly resolution. 221 | string assemblyName = System.IO.Path.GetFileNameWithoutExtension(resolvedPath); 222 | assembly = GetAssemblyIfLoaded(assemblyName); 223 | if (assembly == null) 224 | { 225 | // Really have to load it. 226 | if (LoadFromBytes) 227 | { 228 | // We need to be careful here to not re-load the assembly if it had already been loaded, 229 | // e.g. as a dependency of an assembly loaded earlier. 230 | // In that case we won't be able to have the library 'LoadFromBytes'. 231 | byte[] bytes = File.ReadAllBytes(resolvedPath); 232 | 233 | string pdbPath = System.IO.Path.ChangeExtension(resolvedPath, "pdb"); 234 | if (File.Exists(pdbPath)) 235 | { 236 | byte[] pdbBytes = File.ReadAllBytes(pdbPath); 237 | assembly = Assembly.Load(bytes, pdbBytes); 238 | } 239 | else 240 | { 241 | assembly = Assembly.Load(bytes); 242 | } 243 | } 244 | else 245 | { 246 | assembly = Assembly.LoadFrom(resolvedPath); 247 | } 248 | } 249 | string resolvedTypeLibPath = null; 250 | if (!string.IsNullOrEmpty(TypeLibPath)) 251 | { 252 | resolvedTypeLibPath = DnaLibrary.ResolvePath(TypeLibPath, pathResolveRoot); // null is unresolved 253 | if (resolvedTypeLibPath == null) 254 | { 255 | resolvedTypeLibPath = DnaLibrary.ResolvePath(TypeLibPath, System.IO.Path.GetDirectoryName(resolvedPath)); 256 | } 257 | } 258 | else 259 | { 260 | // Check for .tlb with same name next to resolvedPath 261 | string tlbCheck = System.IO.Path.ChangeExtension(resolvedPath, "tlb"); 262 | if (System.IO.File.Exists(tlbCheck)) 263 | { 264 | resolvedTypeLibPath = tlbCheck; 265 | } 266 | } 267 | list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, resolvedTypeLibPath, dnaLibrary)); 268 | return list; 269 | } 270 | } 271 | catch (Exception e) 272 | { 273 | // Assembly could not be loaded. 274 | LogDisplay.WriteLine("External library could not be registered - Path: " + Path); 275 | LogDisplay.WriteLine(" Error: " + e.Message); 276 | return list; 277 | } 278 | } 279 | 280 | // A copy of this method lives in ExcelDna.Loader - AssemblyManager.cs 281 | private static Assembly GetAssemblyIfLoaded(string assemblyName) 282 | { 283 | Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 284 | foreach (Assembly loadedAssembly in assemblies) 285 | { 286 | string loadedAssemblyName = loadedAssembly.FullName.Split(',')[0]; 287 | if (string.Equals(assemblyName, loadedAssemblyName, StringComparison.OrdinalIgnoreCase)) 288 | return loadedAssembly; 289 | } 290 | return null; 291 | } 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/GuidUtility.cs: -------------------------------------------------------------------------------- 1 | // This code retrieved from: https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs 2 | // on 19 January 2014, having this license: 3 | 4 | // Copyright 2007-2013 Logos Bible Software 5 | 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | // this software and associated documentation files (the "Software"), to deal in 8 | // the Software without restriction, including without limitation the rights to 9 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10 | // of the Software, and to permit persons to whom the Software is furnished to do 11 | // so, subject to the following conditions: 12 | 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | using System; 25 | using System.Security.Cryptography; 26 | using System.Text; 27 | 28 | namespace ExcelDna.Integration 29 | { 30 | /// 31 | /// Helper methods for working with . 32 | /// 33 | internal static class GuidUtility 34 | { 35 | /// 36 | /// Creates a name-based UUID using the algorithm from RFC 4122 §4.3. 37 | /// 38 | /// The ID of the namespace. 39 | /// The name (within that namespace). 40 | /// A UUID derived from the namespace and name. 41 | /// See Generating a deterministic GUID. 42 | public static Guid Create(Guid namespaceId, string name) 43 | { 44 | return Create(namespaceId, name, 5); 45 | } 46 | 47 | /// 48 | /// Creates a name-based UUID using the algorithm from RFC 4122 §4.3. 49 | /// 50 | /// The ID of the namespace. 51 | /// The name (within that namespace). 52 | /// The version number of the UUID to create; this value must be either 53 | /// 3 (for MD5 hashing) or 5 (for SHA-1 hashing). 54 | /// A UUID derived from the namespace and name. 55 | /// See Generating a deterministic GUID. 56 | public static Guid Create(Guid namespaceId, string name, int version) 57 | { 58 | if (name == null) 59 | throw new ArgumentNullException("name"); 60 | if (version != 3 && version != 5) 61 | throw new ArgumentOutOfRangeException("version", "version must be either 3 or 5."); 62 | 63 | // convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3) 64 | // ASSUME: UTF-8 encoding is always appropriate 65 | byte[] nameBytes = Encoding.UTF8.GetBytes(name); 66 | 67 | // convert the namespace UUID to network order (step 3) 68 | byte[] namespaceBytes = namespaceId.ToByteArray(); 69 | SwapByteOrder(namespaceBytes); 70 | 71 | // comput the hash of the name space ID concatenated with the name (step 4) 72 | byte[] hash; 73 | using (HashAlgorithm algorithm = version == 3 ? (HashAlgorithm)MD5.Create() : SHA1.Create()) 74 | { 75 | algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, null, 0); 76 | algorithm.TransformFinalBlock(nameBytes, 0, nameBytes.Length); 77 | hash = algorithm.Hash; 78 | } 79 | 80 | // most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12) 81 | byte[] newGuid = new byte[16]; 82 | Array.Copy(hash, 0, newGuid, 0, 16); 83 | 84 | // set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the appropriate 4-bit version number from Section 4.1.3 (step 8) 85 | newGuid[6] = (byte)((newGuid[6] & 0x0F) | (version << 4)); 86 | 87 | // set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively (step 10) 88 | newGuid[8] = (byte)((newGuid[8] & 0x3F) | 0x80); 89 | 90 | // convert the resulting UUID to local byte order (step 13) 91 | SwapByteOrder(newGuid); 92 | return new Guid(newGuid); 93 | } 94 | 95 | /// 96 | /// The namespace for fully-qualified domain names (from RFC 4122, Appendix C). 97 | /// 98 | public static readonly Guid DnsNamespace = new Guid("6ba7b810-9dad-11d1-80b4-00c04fd430c8"); 99 | 100 | /// 101 | /// The namespace for URLs (from RFC 4122, Appendix C). 102 | /// 103 | public static readonly Guid UrlNamespace = new Guid("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); 104 | 105 | /// 106 | /// The namespace for ISO OIDs (from RFC 4122, Appendix C). 107 | /// 108 | public static readonly Guid IsoOidNamespace = new Guid("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); 109 | 110 | // Converts a GUID (expressed as a byte array) to/from network order (MSB-first). 111 | internal static void SwapByteOrder(byte[] guid) 112 | { 113 | SwapBytes(guid, 0, 3); 114 | SwapBytes(guid, 1, 2); 115 | SwapBytes(guid, 4, 5); 116 | SwapBytes(guid, 6, 7); 117 | } 118 | 119 | private static void SwapBytes(byte[] guid, int left, int right) 120 | { 121 | byte temp = guid[left]; 122 | guid[left] = guid[right]; 123 | guid[right] = temp; 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/IExcelAddIn.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | namespace ExcelDna.Integration 26 | { 27 | public interface IExcelAddIn 28 | { 29 | void AutoOpen(); 30 | void AutoClose(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/LogDisplay.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelDna.Logging 2 | { 3 | partial class LogDisplayForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.btnClear = new System.Windows.Forms.Button(); 32 | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); 33 | this.btnCopy = new System.Windows.Forms.Button(); 34 | this.logMessages = new System.Windows.Forms.ListView(); 35 | this.logMessageText = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 36 | this.btnSaveErrors = new System.Windows.Forms.Button(); 37 | this.tableLayoutPanel1.SuspendLayout(); 38 | this.SuspendLayout(); 39 | // 40 | // btnClear 41 | // 42 | this.btnClear.Location = new System.Drawing.Point(175, 3); 43 | this.btnClear.Name = "btnClear"; 44 | this.btnClear.Size = new System.Drawing.Size(80, 24); 45 | this.btnClear.TabIndex = 3; 46 | this.btnClear.Text = "C&lear"; 47 | this.btnClear.UseVisualStyleBackColor = true; 48 | this.btnClear.Click += new System.EventHandler(this.btnClear_Click); 49 | // 50 | // tableLayoutPanel1 51 | // 52 | this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 53 | this.tableLayoutPanel1.ColumnCount = 4; 54 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); 55 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); 56 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); 57 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); 58 | this.tableLayoutPanel1.Controls.Add(this.btnCopy, 1, 0); 59 | this.tableLayoutPanel1.Controls.Add(this.logMessages, 0, 1); 60 | this.tableLayoutPanel1.Controls.Add(this.btnSaveErrors, 0, 0); 61 | this.tableLayoutPanel1.Controls.Add(this.btnClear, 2, 0); 62 | this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; 63 | this.tableLayoutPanel1.Location = new System.Drawing.Point(5, 5); 64 | this.tableLayoutPanel1.Name = "tableLayoutPanel1"; 65 | this.tableLayoutPanel1.RowCount = 2; 66 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); 67 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); 68 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); 69 | this.tableLayoutPanel1.Size = new System.Drawing.Size(622, 284); 70 | this.tableLayoutPanel1.TabIndex = 3; 71 | // 72 | // btnCopy 73 | // 74 | this.btnCopy.Location = new System.Drawing.Point(89, 3); 75 | this.btnCopy.Name = "btnCopy"; 76 | this.btnCopy.Size = new System.Drawing.Size(80, 24); 77 | this.btnCopy.TabIndex = 4; 78 | this.btnCopy.Text = "&Copy"; 79 | this.btnCopy.UseVisualStyleBackColor = true; 80 | this.btnCopy.Click += new System.EventHandler(this.btnCopy_Click); 81 | // 82 | // logMessages 83 | // 84 | this.logMessages.BackColor = System.Drawing.SystemColors.Window; 85 | this.logMessages.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 86 | this.logMessageText}); 87 | this.tableLayoutPanel1.SetColumnSpan(this.logMessages, 4); 88 | this.logMessages.Dock = System.Windows.Forms.DockStyle.Fill; 89 | this.logMessages.FullRowSelect = true; 90 | this.logMessages.GridLines = true; 91 | this.logMessages.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; 92 | this.logMessages.Location = new System.Drawing.Point(3, 33); 93 | this.logMessages.Name = "logMessages"; 94 | this.logMessages.Size = new System.Drawing.Size(616, 248); 95 | this.logMessages.TabIndex = 1; 96 | this.logMessages.UseCompatibleStateImageBehavior = false; 97 | this.logMessages.View = System.Windows.Forms.View.Details; 98 | this.logMessages.VirtualMode = true; 99 | this.logMessages.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.logMessages_RetrieveVirtualItem); 100 | // 101 | // logMessageText 102 | // 103 | this.logMessageText.Width = 585; 104 | // 105 | // btnSaveErrors 106 | // 107 | this.btnSaveErrors.Location = new System.Drawing.Point(3, 3); 108 | this.btnSaveErrors.Name = "btnSaveErrors"; 109 | this.btnSaveErrors.Size = new System.Drawing.Size(80, 24); 110 | this.btnSaveErrors.TabIndex = 2; 111 | this.btnSaveErrors.Text = "&Save ..."; 112 | this.btnSaveErrors.UseVisualStyleBackColor = true; 113 | this.btnSaveErrors.Click += new System.EventHandler(this.btnSaveErrors_Click); 114 | // 115 | // LogDisplayForm 116 | // 117 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 118 | this.AutoScroll = true; 119 | this.ClientSize = new System.Drawing.Size(632, 294); 120 | this.Controls.Add(this.tableLayoutPanel1); 121 | this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 122 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; 123 | this.KeyPreview = true; 124 | this.MinimumSize = new System.Drawing.Size(450, 270); 125 | this.Name = "LogDisplayForm"; 126 | this.Padding = new System.Windows.Forms.Padding(5); 127 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 128 | this.Text = "Excel-Dna Error Display"; 129 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LogDisplayForm_FormClosing); 130 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.LogDisplayForm_KeyDown); 131 | this.tableLayoutPanel1.ResumeLayout(false); 132 | this.ResumeLayout(false); 133 | 134 | } 135 | 136 | #endregion 137 | 138 | private System.Windows.Forms.Button btnClear; 139 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; 140 | private System.Windows.Forms.ListView logMessages; 141 | private System.Windows.Forms.Button btnSaveErrors; 142 | private System.Windows.Forms.ColumnHeader logMessageText; 143 | private System.Windows.Forms.Button btnCopy; 144 | 145 | } 146 | } -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/LogDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Windows.Forms; 9 | 10 | using ExcelDna.Integration; 11 | 12 | namespace ExcelDna.Logging 13 | { 14 | 15 | internal partial class LogDisplayForm : Form 16 | { 17 | [DllImport("user32.dll")] 18 | static extern IntPtr SetFocus(IntPtr hWnd); 19 | internal static LogDisplayForm _form; 20 | 21 | internal static void ShowForm() 22 | { 23 | if (_form == null) 24 | { 25 | _form = new LogDisplayForm(); 26 | } 27 | 28 | if (_form.Visible == false) 29 | { 30 | _form.Show(null); 31 | // SetFocus(ExcelDnaUtil.WindowHandle); 32 | } 33 | } 34 | 35 | internal static void HideForm() 36 | { 37 | if (_form != null) 38 | { 39 | _form.updateTimer.Enabled = false; 40 | _form.Close(); 41 | } 42 | } 43 | 44 | System.Windows.Forms.Timer updateTimer; 45 | 46 | internal LogDisplayForm() 47 | { 48 | InitializeComponent(); 49 | Text = DnaLibrary.CurrentLibraryName + " - Log Display"; 50 | CenterToParent(); 51 | logMessages.VirtualListSize = LogDisplay.LogStrings.Count; 52 | updateTimer = new System.Windows.Forms.Timer(); 53 | updateTimer.Interval = 250; 54 | updateTimer.Tick += updateTimer_Tick; 55 | updateTimer.Enabled = true; 56 | } 57 | 58 | void updateTimer_Tick(object sender, EventArgs e) 59 | { 60 | try 61 | { 62 | if (!IsDisposed && updateTimer.Enabled && LogDisplay.LogStringsUpdated) 63 | { 64 | // CONSIDER: There are some race conditions here 65 | // - but I'd rather have some log mis-painting than deadlock between the UI thread and a calculation thread. 66 | logMessages.VirtualListSize = LogDisplay.LogStrings.Count; 67 | LogDisplay.LogStringsUpdated = false; 68 | //ClearCache(); 69 | logMessages.Invalidate(); 70 | logMessages.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent); 71 | // Debug.Print("LogDisplayForm.updateTimer_Tick - Updated to " + logMessages.VirtualListSize + " messages"); 72 | } 73 | } 74 | catch (Exception ex) 75 | { 76 | Debug.Print("Exception in updateTime_Tick: " + ex); 77 | } 78 | } 79 | 80 | private ListViewItem MakeItem(int messageIndex) 81 | { 82 | string message; 83 | try 84 | { 85 | message = LogDisplay.LogStrings[messageIndex]; 86 | if (message.Length > 259) 87 | { 88 | // truncating here, rather than when we insert into the list, 89 | // so that save and export will preserve the full string. 90 | message = message.Substring(0, 253) + " [...]"; 91 | } 92 | } 93 | catch 94 | { 95 | message = " "; 96 | } 97 | 98 | return new ListViewItem(message); 99 | } 100 | 101 | public void Clear() 102 | { 103 | logMessages.VirtualListSize = 0; 104 | logMessages.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent); 105 | } 106 | 107 | private void LogDisplayForm_FormClosing(object sender, FormClosingEventArgs e) 108 | { 109 | _form.updateTimer.Enabled = false; 110 | _form = null; 111 | LogDisplay.IsFormVisible = false; 112 | try 113 | { 114 | SetFocus(ExcelDnaUtil.WindowHandle); 115 | } 116 | catch { } // Probably not in Excel !? 117 | } 118 | 119 | private void btnSaveErrors_Click(object sender, EventArgs e) 120 | { 121 | SaveFileDialog sfd = new SaveFileDialog(); 122 | sfd.DefaultExt = "txt"; 123 | sfd.Filter = "Text File (*.txt)|*.txt|All Files (*.*)|*.*"; 124 | sfd.Title = "Save Error List As"; 125 | DialogResult result = sfd.ShowDialog(); 126 | if (result == DialogResult.OK) 127 | { 128 | File.WriteAllText(sfd.FileName, LogDisplay.GetAllText()); 129 | } 130 | } 131 | 132 | private void btnClear_Click(object sender, EventArgs e) 133 | { 134 | LogDisplay.Clear(); 135 | Clear(); 136 | } 137 | 138 | private void LogDisplayForm_KeyDown(object sender, KeyEventArgs e) 139 | { 140 | if (e.KeyCode == Keys.Escape) 141 | { 142 | Close(); 143 | } 144 | } 145 | 146 | private void btnCopy_Click(object sender, EventArgs e) 147 | { 148 | string allText = LogDisplay.GetAllText(); 149 | if (allText != null) 150 | { 151 | Clipboard.SetText(allText); 152 | } 153 | } 154 | 155 | private void logMessages_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) 156 | { 157 | e.Item = MakeItem(e.ItemIndex); 158 | } 159 | } 160 | 161 | public class MessageBufferChangedEventArgs : EventArgs 162 | { 163 | public enum MessageBufferChangeType 164 | { 165 | Clear, 166 | RemoveFirst, 167 | AddLast 168 | } 169 | 170 | public string AddedMessage { get; set; } 171 | 172 | public MessageBufferChangeType ChangeType { get; set; } 173 | 174 | public MessageBufferChangedEventArgs(MessageBufferChangeType changeType) 175 | { 176 | ChangeType = changeType; 177 | } 178 | 179 | public MessageBufferChangedEventArgs(string addedMessage) 180 | { 181 | ChangeType = MessageBufferChangeType.AddLast; 182 | AddedMessage = addedMessage; 183 | } 184 | } 185 | 186 | public enum DisplayOrder 187 | { 188 | NewestLast, 189 | NewestFirst 190 | } 191 | 192 | public static class LogDisplay 193 | { 194 | internal static List LogStrings; 195 | internal static bool LogStringsUpdated; 196 | const int maxLogSize = 10000; // Max number of strings we'll allow in the buffer. Individual strings are unbounded. 197 | internal static object SyncRoot = new object(); 198 | internal static bool IsFormVisible; 199 | 200 | // _syncContext is null until we call CreateInstance, which 201 | static SynchronizationContext _syncContext; 202 | 203 | // This must be called on the main Excel thread. 204 | internal static void CreateInstance() 205 | { 206 | LogStrings = new List(); 207 | LogStringsUpdated = true; 208 | _syncContext = SynchronizationContext.Current; 209 | IsFormVisible = false; 210 | if (_syncContext == null) 211 | { 212 | _syncContext = new WindowsFormsSynchronizationContext(); 213 | //Debug.Print("LogDisplay.CreateInstance - Creating SyncContext on thread: " + Thread.CurrentThread.ManagedThreadId); 214 | } 215 | } 216 | 217 | public static void Show() 218 | { 219 | _syncContext.Post(delegate(object state) 220 | { 221 | LogDisplayForm.ShowForm(); 222 | }, null); 223 | } 224 | 225 | public static void Hide() 226 | { 227 | _syncContext.Post(delegate(object state) 228 | { 229 | LogDisplayForm.HideForm(); 230 | }, null); 231 | } 232 | 233 | [Obsolete("Rather use LogDisplay.Clear() and LogDisplay.WriteLine(...)")] 234 | public static void SetText(string text) 235 | { 236 | WriteLine(text); 237 | } 238 | 239 | // This might be called from any calculation thread - also displays the form. 240 | public static void WriteLine(string format, params object[] args) 241 | { 242 | //Debug.WriteLine("LogDisplay.WriteLine start on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId); 243 | lock (SyncRoot) 244 | { 245 | if (!IsFormVisible) 246 | { 247 | Show(); 248 | IsFormVisible = true; 249 | } 250 | RecordLine(format, args); 251 | } 252 | //Debug.WriteLine("LogDisplay.WriteLine completed in thread " + System.Threading.Thread.CurrentThread.ManagedThreadId); 253 | } 254 | 255 | // This might be called from any calculation thread 256 | // Does not force a Show 257 | public static void RecordLine(string format, params object[] args) 258 | { 259 | lock (SyncRoot) 260 | { 261 | string message = string.Format(format, args); 262 | string[] messageLines = message.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); 263 | if (DisplayOrder == DisplayOrder.NewestLast) 264 | { 265 | // Insert at the end 266 | LogStrings.AddRange(messageLines); 267 | } 268 | else 269 | { 270 | // Insert at the beginning. 271 | LogStrings.InsertRange(0, messageLines); 272 | } 273 | TruncateLog(); 274 | LogStringsUpdated = true; 275 | } 276 | } 277 | 278 | static void TruncateLog() 279 | { 280 | while (LogStrings.Count > maxLogSize) 281 | { 282 | if (DisplayOrder == DisplayOrder.NewestLast) 283 | { 284 | // Remove from the front 285 | LogStrings.RemoveAt(0); 286 | } 287 | else 288 | { 289 | // Remove from the back 290 | LogStrings.RemoveAt(LogStrings.Count - 1); 291 | } 292 | } 293 | } 294 | 295 | public static void Clear() 296 | { 297 | lock (SyncRoot) 298 | { 299 | LogStrings.Clear(); 300 | LogStringsUpdated = true; 301 | } 302 | } 303 | 304 | internal static string GetAllText() 305 | { 306 | StringBuilder sb = new StringBuilder(); 307 | foreach (string msg in LogStrings) 308 | { 309 | sb.AppendLine(msg); 310 | } 311 | return sb.ToString(); 312 | } 313 | 314 | static DisplayOrder _displayOrder; 315 | public static DisplayOrder DisplayOrder 316 | { 317 | get { return _displayOrder; } 318 | set 319 | { 320 | if (_displayOrder != value) 321 | { 322 | _displayOrder = value; 323 | LogStrings.Reverse(); 324 | LogStringsUpdated = true; 325 | } 326 | } 327 | } 328 | 329 | } 330 | } -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/LogDisplay.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/MenuManager.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using System.Diagnostics; 28 | using ExcelDna.Integration.CustomUI; 29 | 30 | namespace ExcelDna.Integration 31 | { 32 | /// 33 | /// The MenuManager is used by the Loader. 34 | /// TODO: Can we integrate with ExcelCommandBars? 35 | /// Hierarchical menus. 36 | /// 37 | 38 | // CAUTION: This 'internal' class is called via reflection by the ExcelDna Loader. 39 | internal static class MenuManager 40 | { 41 | static IMenuManager _menuManager; 42 | static MenuManager() 43 | { 44 | if (ExcelDnaUtil.SafeIsExcelVersionPre15) 45 | { 46 | _menuManager = new ExcelPre15MenuManager(); 47 | } 48 | else 49 | { 50 | _menuManager = new Excel15MenuManager(); 51 | } 52 | } 53 | 54 | // These methods are called from XlRegistration via reflection 55 | // The binding is in IntegrationHelpers 56 | static void AddCommandMenu(string commandName, string menuName, string menuText, string description, string shortCut, string helpTopic) 57 | { 58 | _menuManager.AddCommandMenu(commandName, menuName, menuText, description, shortCut, helpTopic); 59 | } 60 | 61 | static void RemoveCommandMenus() 62 | { 63 | _menuManager.RemoveCommandMenus(); 64 | } 65 | } 66 | 67 | interface IMenuManager 68 | { 69 | void AddCommandMenu(string commandName, string menuName, string menuText, string description, string shortCut, string helpTopic); 70 | void RemoveCommandMenus(); 71 | } 72 | 73 | class ExcelPre15MenuManager : IMenuManager 74 | { 75 | private class MenuEntry 76 | { 77 | internal readonly string CommandName; 78 | internal readonly string MenuName; 79 | internal readonly string MenuText; 80 | 81 | internal MenuEntry(string commandName, string menuName, string menuText) 82 | { 83 | CommandName = commandName; 84 | MenuName = menuName; 85 | MenuText = menuText; 86 | } 87 | } 88 | 89 | readonly List _addedMenus = new List(); 90 | readonly List _addedMenuEntries = new List(); 91 | 92 | public void AddCommandMenu(string commandName, string menuName, string menuText, string description, string shortCut, string helpTopic) 93 | { 94 | try // Basically suppress problems here..? 95 | { 96 | bool done = false; 97 | if (!_addedMenus.Contains(menuName)) 98 | { 99 | // Check if the menu exists 100 | object result = XlCall.Excel(XlCall.xlfGetBar, 1.0 /*Worksheet and Macro sheet*/, 101 | menuName, 0); 102 | if (result is ExcelError) 103 | { 104 | // Add the Menu 105 | // DOCUMENT: Description, HelpTopic ??? 106 | // Throws Access violation exception Excel if I add a string to description or helptopic 107 | XlCall.Excel(XlCall.xlfAddMenu, 1.0 /*Worksheet and Macro sheet*/, 108 | new object[,] { { menuName, null, null, null, null}, 109 | { menuText, commandName, 110 | null/*shortcut_key (Mac Only)*/, 111 | null, // mi.Description, 112 | null /*mi.HelpTopic*/} }); 113 | _addedMenus.Add(menuName); 114 | done = true; 115 | } 116 | } 117 | if (!done) 118 | { 119 | // Check if command exists 120 | object result = XlCall.Excel(XlCall.xlfGetBar, 1.0 /*Worksheet and Macro sheet*/, 121 | menuName, menuText); 122 | if (result is ExcelError) 123 | { 124 | // Register the new command on the menu 125 | XlCall.Excel(XlCall.xlfAddCommand, 126 | 1.0 /*Worksheet and Macro sheet*/, 127 | menuName, 128 | new object[] { 129 | menuText, 130 | commandName, 131 | null/*shortcut_key (Mac Only)*/, 132 | null, // mi.Description, 133 | null /*mi.HelpTopic*/}); 134 | _addedMenuEntries.Add(new MenuEntry(commandName, menuName, menuText)); 135 | } 136 | } 137 | } 138 | catch (Exception e) 139 | { 140 | Debug.WriteLine(e.Message); 141 | } 142 | } 143 | 144 | public void RemoveCommandMenus() 145 | { 146 | // First take out menus and commands 147 | foreach (MenuEntry me in _addedMenuEntries) 148 | { 149 | try 150 | { 151 | XlCall.Excel(XlCall.xlfDeleteCommand, 152 | 1.0 /*Worksheet and Macro sheet*/, 153 | me.MenuName, 154 | me.MenuText); 155 | } 156 | catch (Exception e) 157 | { 158 | Debug.WriteLine(e.Message); 159 | } 160 | } 161 | _addedMenuEntries.Clear(); 162 | 163 | foreach (string menu in _addedMenus) 164 | { 165 | try 166 | { 167 | XlCall.Excel(XlCall.xlfDeleteMenu, 168 | 1.0 /*Worksheet and Macro sheet*/, 169 | menu); 170 | } 171 | catch (Exception e) 172 | { 173 | Debug.WriteLine(e.Message); 174 | } 175 | } 176 | _addedMenus.Clear(); 177 | } 178 | } 179 | 180 | class Excel15MenuManager : IMenuManager 181 | { 182 | readonly Dictionary _foundMenus = new Dictionary(); 183 | readonly List _addedMenus = new List(); 184 | readonly List _addedButtons = new List(); 185 | 186 | public void AddCommandMenu(string commandName, string menuName, string menuText, string description, string shortCut, string helpTopic) 187 | { 188 | try // Basically suppress problems here..? 189 | { 190 | CommandBarPopup menu; 191 | if (!_foundMenus.TryGetValue(menuName, out menu)) 192 | { 193 | // We've not seen this menu before 194 | 195 | // Check if the menu exists 196 | CommandBars commandBars = ExcelCommandBarUtil.GetCommandBars(); 197 | CommandBar worksheetBar = commandBars[1]; 198 | CommandBarControls controls = worksheetBar.Controls; 199 | int controlCount = controls.Count(); 200 | 201 | for (int i = 1; i <= controlCount; i++) 202 | { 203 | CommandBarControl control = controls[i]; 204 | if (control.Caption == menuName && control is CommandBarPopup) 205 | { 206 | menu = (CommandBarPopup)control; 207 | _foundMenus[menuName] = menu; 208 | break; 209 | } 210 | } 211 | 212 | if (menu == null) 213 | { 214 | // Make a new menu 215 | menu = controls.AddPopup(menuName); 216 | menu.Caption = menuName; 217 | _addedMenus.Add(menu); 218 | _foundMenus[menuName] = menu; 219 | } 220 | } 221 | 222 | CommandBarControls menuButtons = menu.Controls; 223 | int buttonCount = menu.Controls.Count(); 224 | for (int i = 1; i <= buttonCount; i++) 225 | { 226 | CommandBarControl button = menuButtons[i]; 227 | if (button.Caption == menuText && button is CommandBarButton) 228 | { 229 | button.OnAction = commandName; 230 | return; 231 | } 232 | } 233 | 234 | // If we're here, need to add a button. 235 | CommandBarButton newButton = menuButtons.AddButton(); 236 | newButton.Caption = menuText; 237 | newButton.OnAction = commandName; 238 | _addedButtons.Add(newButton); 239 | } 240 | catch (Exception e) 241 | { 242 | Debug.WriteLine(e.Message); 243 | } 244 | } 245 | 246 | public void RemoveCommandMenus() 247 | { 248 | foreach (CommandBarButton button in _addedButtons) 249 | { 250 | button.Delete(true); 251 | } 252 | 253 | foreach (CommandBarPopup popup in _addedMenus) 254 | { 255 | popup.Delete(true); 256 | } 257 | } 258 | } 259 | } 260 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ExcelDna Integration Library")] 9 | [assembly: AssemblyDescription("Integration library for ExcelDna")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Excel-DNA Add-In Framework for Microsoft Excel")] 13 | [assembly: AssemblyCopyright("Copyright © 2005-2014 Govert van Drimmelen")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("97d61fc9-f052-434d-8bd4-190f606567e3")] 24 | 25 | [assembly: CLSCompliant(true)] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | [assembly: AssemblyVersion("0.32.*")] 38 | [assembly: AssemblyFileVersion("0.32.25.1")] 39 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/Reference.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Xml.Serialization; 27 | 28 | namespace ExcelDna.Integration 29 | { 30 | [Serializable] 31 | [XmlType(AnonymousType = true)] 32 | public class Reference 33 | { 34 | // DOCUMENT: AssemblyPath is obsolete, and only used as Path if the Path itself is null. 35 | // If Path is empty or cannot be resolved to a real file, LoadWithPartialName is called with Name, so that Name="System.Windows.Forms" and "Microsoft.Office.Interop.Excel" will work. 36 | 37 | [XmlAttribute] 38 | public string Name; 39 | 40 | // [Obsolete("Please use Path attribute.")] 41 | // (Can't mark it as Obsolete since serilizer will then ignore, breaking backward compatibility.) 42 | [XmlAttribute] 43 | public string AssemblyPath; 44 | 45 | private string _path; 46 | [XmlAttribute] 47 | public string Path 48 | { 49 | get 50 | { 51 | if (_path == null) 52 | { 53 | return AssemblyPath; 54 | } 55 | return _path; 56 | } 57 | set 58 | { 59 | _path = value; 60 | } 61 | } 62 | 63 | [XmlAttribute] 64 | public bool Pack; 65 | 66 | public Reference() 67 | { 68 | } 69 | 70 | public Reference(string path) 71 | { 72 | Path = path; 73 | } 74 | } 75 | 76 | [Serializable] 77 | [XmlType(AnonymousType = true)] 78 | public class Image 79 | { 80 | [XmlAttribute] 81 | public string Name; 82 | 83 | [XmlAttribute] 84 | public string Path; 85 | 86 | [XmlAttribute] 87 | public bool Pack; 88 | 89 | public Image() 90 | { 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/RegistrationInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Reflection; 5 | 6 | namespace ExcelDna.Integration 7 | { 8 | static class RegistrationInfo 9 | { 10 | static string _registrationInfoName = null; 11 | static double _registrationInfoRegistrationId; 12 | // We register the two extension helpers: 13 | // * SyncMacro_XXXXX which is used for the thread-safe RTD support and QueueAsMacro mechanism 14 | // * RegistrationInfo_XXXX which is used to retrieve the xlfRegister call info. 15 | // In both cases the XXXX is replaced with the Guid from the .xll path 16 | internal static void Register() 17 | { 18 | // RegistrationInfo is supported for Excel 2007+ only 19 | if (ExcelDnaUtil.ExcelVersion < 12.0) return; 20 | 21 | _registrationInfoName = RegistrationInfoName(ExcelDnaUtil.XllPath); 22 | 23 | object[] registerParameters = new object[6]; 24 | registerParameters[0] = ExcelDnaUtil.XllPath; 25 | registerParameters[1] = "RegistrationInfo"; 26 | registerParameters[2] = "QQ"; // Takes XLOPER12, returns XLOPER12 27 | registerParameters[3] = _registrationInfoName; 28 | registerParameters[4] = null; 29 | registerParameters[5] = 0; // hidden function 30 | 31 | object xlCallResult; 32 | XlCall.TryExcel(XlCall.xlfRegister, out xlCallResult, registerParameters); 33 | Debug.Print("Register RegistrationInfo - XllPath={0}, ProcName={1}, FunctionType={2}, MethodName={3} - Result={4}", 34 | registerParameters[0], registerParameters[1], registerParameters[2], registerParameters[3], xlCallResult); 35 | if (xlCallResult is double) 36 | { 37 | _registrationInfoRegistrationId = (double)xlCallResult; 38 | } 39 | else 40 | { 41 | throw new InvalidOperationException("Synchronization macro registration failed."); 42 | } 43 | } 44 | 45 | internal static void Unregister() 46 | { 47 | object xlCallResult; 48 | XlCall.TryExcel(XlCall.xlfUnregister, out xlCallResult, _registrationInfoRegistrationId); 49 | XlCall.TryExcel(XlCall.xlfRegister, out xlCallResult, ExcelDnaUtil.XllPath, "xlAutoRemove", "I", _registrationInfoName, ExcelMissing.Value, 2); 50 | if (xlCallResult is double) 51 | { 52 | double fakeRegisterId = (double)xlCallResult; 53 | XlCall.TryExcel(XlCall.xlfSetName, out xlCallResult, _registrationInfoName); 54 | XlCall.TryExcel(XlCall.xlfUnregister, out xlCallResult, fakeRegisterId); 55 | } 56 | } 57 | 58 | // Name of the Registration Helper function, registered in ExcelIntegration.RegisterRegistrationInfo 59 | static string RegistrationInfoName(string xllPath) 60 | { 61 | return "RegistrationInfo_" + ExcelDnaUtil.GuidFromXllPath(xllPath).ToString("N"); 62 | } 63 | 64 | // Public function to get registration info for this or other Excel-DNA .xlls 65 | // Return #N/A if the matching RegistrationInfo function is not found. 66 | internal static object GetRegistrationInfo(string xllPath, double registrationInfoVersion) 67 | { 68 | string regInfoName = RegistrationInfoName(xllPath); 69 | object result; 70 | 71 | // To prevent the error dialog, we first call xlfEvaluate with the name 72 | if (XlCall.Excel(XlCall.xlfEvaluate, regInfoName) is double && 73 | XlCall.TryExcel(XlCall.xlUDF, out result, regInfoName, registrationInfoVersion) == XlCall.XlReturn.XlReturnSuccess) 74 | { 75 | return result; 76 | } 77 | 78 | return ExcelError.ExcelErrorNA; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/SourceItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2005-2014 Govert van Drimmelen 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | Govert van Drimmelen 22 | govert@icon.co.za 23 | */ 24 | 25 | using System; 26 | using System.Text; 27 | using System.Xml.Serialization; 28 | using System.IO; 29 | using System.Diagnostics; 30 | 31 | namespace ExcelDna.Integration 32 | { 33 | [Serializable] 34 | [XmlType(AnonymousType = true)] 35 | public class SourceItem 36 | { 37 | private string _Name; 38 | [XmlAttribute] 39 | public string Name 40 | { 41 | get { return _Name; } 42 | set { _Name = value; } 43 | } 44 | 45 | private string _Code; 46 | [XmlText] 47 | public string Code 48 | { 49 | get { return _Code; } 50 | set { _Code = value; } 51 | } 52 | 53 | private string _Path; 54 | [XmlAttribute] 55 | public string Path 56 | { 57 | get { return _Path; } 58 | set { _Path = value; } 59 | } 60 | 61 | [XmlAttribute] 62 | public bool Pack; 63 | 64 | // Returns the resulting source for this SourceItem. 65 | // If Path is filled in, and file exists, takes source from there. 66 | // Else returns Code value. 67 | public string GetSource(string pathResolveRoot) 68 | { 69 | if (!string.IsNullOrEmpty(Path)) 70 | { 71 | if (Path.StartsWith("packed:")) 72 | { 73 | string resourceName = Path.Substring(7); 74 | byte[] sourceBytes = ExcelIntegration.GetSourceBytes(resourceName); 75 | return Encoding.UTF8.GetString(sourceBytes); 76 | } 77 | else 78 | { 79 | // Try to read from a file. 80 | string resolvedPath = DnaLibrary.ResolvePath(Path, pathResolveRoot); 81 | if (resolvedPath == null) 82 | { 83 | Debug.Print("Source path {0} could not be resolved.", Path); 84 | } 85 | else 86 | { 87 | return File.ReadAllText(resolvedPath).Trim(); 88 | } 89 | } 90 | } 91 | return Code; 92 | } 93 | 94 | public SourceItem() 95 | { 96 | } 97 | 98 | internal SourceItem(string code) 99 | { 100 | Code = code; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/bin/Release/ExcelDna.Integration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/Lib/ExcelDna.Integration/bin/Release/ExcelDna.Integration.dll -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/bin/x64/Release/ExcelDna.Integration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/Lib/ExcelDna.Integration/bin/x64/Release/ExcelDna.Integration.dll -------------------------------------------------------------------------------- /Lib/ExcelDna.Integration/bin/x86/Release/ExcelDna.Integration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/Lib/ExcelDna.Integration/bin/x86/Release/ExcelDna.Integration.dll -------------------------------------------------------------------------------- /Lib/Extract4/Enums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Extract4 8 | { 9 | public enum Source 10 | { 11 | YahooJP, 12 | YahooUS, 13 | } 14 | 15 | public enum Field 16 | { 17 | OPEN, 18 | HIGH, 19 | LOW, 20 | CLOSE, 21 | 22 | ASK, 23 | BID, 24 | 25 | ASK_SIZE, 26 | BID_SIZE, 27 | 28 | LAST, 29 | LAST_SEIZE, 30 | 31 | VOLUME 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Lib/Extract4/Extract4.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071} 8 | Library 9 | Properties 10 | Extract4 11 | Extract4 12 | v4.5 13 | 512 14 | ..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | true 36 | bin\x64\Debug\ 37 | DEBUG;TRACE 38 | full 39 | x64 40 | prompt 41 | MinimumRecommendedRules.ruleset 42 | 43 | 44 | bin\x64\Release\ 45 | TRACE 46 | true 47 | pdbonly 48 | x64 49 | prompt 50 | MinimumRecommendedRules.ruleset 51 | 52 | 53 | true 54 | bin\x86\Debug\ 55 | DEBUG;TRACE 56 | full 57 | x86 58 | prompt 59 | MinimumRecommendedRules.ruleset 60 | 61 | 62 | bin\x86\Release\ 63 | TRACE 64 | true 65 | pdbonly 66 | x86 67 | prompt 68 | MinimumRecommendedRules.ruleset 69 | 70 | 71 | 72 | ..\..\MarketDataDNA\packages\HtmlAgilityPack.1.4.6\lib\Net45\HtmlAgilityPack.dll 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 99 | -------------------------------------------------------------------------------- /Lib/Extract4/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("Extract4")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Extract4")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("ec64fa3c-7434-48d0-8ac6-bc0c3a90f454")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Lib/Extract4/Web/Extractor_for_Web.cs: -------------------------------------------------------------------------------- 1 | using HtmlAgilityPack; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Extract4.Web 11 | { 12 | public class Extractor_for_Web 13 | { 14 | private readonly string baseJpUrl = "http://stocks.finance.yahoo.co.jp/stocks/detail/?code="; 15 | private readonly string baseUsUrl = "http://finance.yahoo.com/q?s="; 16 | private string html; 17 | 18 | private Dictionary> m_nodeName = new Dictionary>(); 19 | private Dictionary> m_marketData = new Dictionary>(); 20 | 21 | public async void Load(Source source, string bland) 22 | { 23 | if (!m_nodeName.ContainsKey(source)) 24 | m_nodeName[source] = new Dictionary(); 25 | 26 | if (!m_marketData.ContainsKey(bland)) 27 | m_marketData[bland] = new Dictionary(); 28 | 29 | string url = ""; 30 | 31 | switch (source) 32 | { 33 | case Source.YahooJP: 34 | url = baseJpUrl + bland; 35 | m_nodeName[source][Field.OPEN] = "/html[1]/body[1]/div[1]/div[2]/div[2]/div[1]/div[3]/div[2]/div[2]/dl[1]/dd[1]/strong[1]"; 36 | m_nodeName[source][Field.HIGH] = "/html[1]/body[1]/div[1]/div[2]/div[2]/div[1]/div[3]/div[2]/div[3]/dl[1]/dd[1]/strong[1]"; 37 | m_nodeName[source][Field.LOW] = "/html[1]/body[1]/div[1]/div[2]/div[2]/div[1]/div[3]/div[2]/div[4]/dl[1]/dd[1]/strong[1]"; 38 | m_nodeName[source][Field.ASK] = "/html[1]/body[1]/div[1]/div[2]/div[2]/div[1]/div[6]/div[1]/table[1]/tr[2]/td[3]/strong[1]"; 39 | m_nodeName[source][Field.BID] = "/html[1]/body[1]/div[1]/div[2]/div[2]/div[1]/div[6]/div[1]/table[1]/tr[3]/td[3]/strong[1]"; 40 | m_nodeName[source][Field.LAST] = "/html[1]/body[1]/div[1]/div[2]/div[2]/div[1]/div[2]/div[1]/table[1]/tr[1]/td[2]"; 41 | break; 42 | case Source.YahooUS: 43 | url = baseUsUrl + bland; 44 | m_nodeName[source][Field.OPEN] = "/html[1]/body[1]/div[4]/div[1]/div[3]/div[3]/div[1]/div[1]/table[1]/tr[2]/td[1]"; 45 | m_nodeName[source][Field.ASK] = "/html[1]/body[1]/div[4]/div[1]/div[3]/div[3]/div[1]/div[1]/table[1]/tr[4]/td[1]/span[1]"; 46 | m_nodeName[source][Field.BID] = "/html[1]/body[1]/div[4]/div[1]/div[3]/div[3]/div[1]/div[1]/table[1]/tr[3]/td[1]/span[1]"; 47 | m_nodeName[source][Field.ASK_SIZE] = "/html[1]/body[1]/div[4]/div[1]/div[3]/div[3]/div[1]/div[1]/table[1]/tr[4]/td[1]/small[1]"; 48 | m_nodeName[source][Field.BID_SIZE] = "/html[1]/body[1]/div[4]/div[1]/div[3]/div[3]/div[1]/div[1]/table[1]/tr[3]/td[1]/small[1]"; 49 | break; 50 | default: 51 | return; 52 | } 53 | 54 | try 55 | { 56 | await Task.Run(() => downloadData(source, url, bland)); 57 | } 58 | catch (Exception err) 59 | { 60 | } 61 | } 62 | 63 | public string GetMarketData(string bland, Field field) 64 | { 65 | if (!m_marketData.ContainsKey(bland) || !m_marketData[bland].ContainsKey(field)) 66 | return bland + " is now loading."; 67 | else 68 | return m_marketData[bland][field]; 69 | } 70 | 71 | private void downloadData(Source source, string url, string bland) 72 | { 73 | WebClient wc = new WebClient(); 74 | Stream st = wc.OpenRead(url); 75 | Encoding enc = Encoding.GetEncoding("utf-8"); 76 | StreamReader sr = new StreamReader(st, enc); 77 | html = sr.ReadToEnd(); 78 | sr.Close(); 79 | st.Close(); 80 | 81 | //HTMLを解析する 82 | HtmlDocument doc = new HtmlDocument(); 83 | doc.LoadHtml(html); 84 | 85 | //XPathで取得するNodeを指定 86 | foreach (Field field in m_nodeName[source].Keys) 87 | { 88 | try 89 | { 90 | doc.DocumentNode.SelectNodes(m_nodeName[source][field]); 91 | var node = doc.DocumentNode.SelectSingleNode(m_nodeName[source][field]); 92 | m_marketData[bland][field] = node.InnerText; 93 | } 94 | catch (Exception err) 95 | { 96 | } 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Lib/Extract4/bin/x64/Release/Extract4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/Lib/Extract4/bin/x64/Release/Extract4.dll -------------------------------------------------------------------------------- /Lib/Extract4/bin/x64/Release/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/Lib/Extract4/bin/x64/Release/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /Lib/Extract4/bin/x86/Release/Extract4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/Lib/Extract4/bin/x86/Release/Extract4.dll -------------------------------------------------------------------------------- /Lib/Extract4/bin/x86/Release/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/Lib/Extract4/bin/x86/Release/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /Lib/Extract4/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30110.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Extract4", "..\Lib\Extract4\Extract4.csproj", "{14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarketDataDNA", "MarketDataDNA\MarketDataDNA.csproj", "{0B8883FE-B214-49AF-884C-6F23F70D12F0}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{F4ACD7B8-C92C-4E02-A03B-CD71B38B8C5E}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelDna.Integration", "..\Lib\ExcelDna.Integration\ExcelDna.Integration.csproj", "{196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Debug|Mixed Platforms = Debug|Mixed Platforms 18 | Debug|x64 = Debug|x64 19 | Debug|x86 = Debug|x86 20 | Release|Any CPU = Release|Any CPU 21 | Release|Mixed Platforms = Release|Mixed Platforms 22 | Release|x64 = Release|x64 23 | Release|x86 = Release|x86 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 29 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|Mixed Platforms.Build.0 = Debug|x86 30 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|x64.ActiveCfg = Debug|x64 31 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|x64.Build.0 = Debug|x64 32 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|x86.ActiveCfg = Debug|x86 33 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Debug|x86.Build.0 = Debug|x86 34 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|Mixed Platforms.ActiveCfg = Release|x86 37 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|Mixed Platforms.Build.0 = Release|x86 38 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|x64.ActiveCfg = Release|x64 39 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|x64.Build.0 = Release|x64 40 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|x86.ActiveCfg = Release|x86 41 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071}.Release|x86.Build.0 = Release|x86 42 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 45 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|Mixed Platforms.Build.0 = Debug|x86 46 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|x64.ActiveCfg = Debug|x64 47 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|x64.Build.0 = Debug|x64 48 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|x86.ActiveCfg = Debug|x86 49 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Debug|x86.Build.0 = Debug|x86 50 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 53 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|Mixed Platforms.Build.0 = Release|Any CPU 54 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|x64.ActiveCfg = Release|x64 55 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|x64.Build.0 = Release|x64 56 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|x86.ActiveCfg = Release|x86 57 | {0B8883FE-B214-49AF-884C-6F23F70D12F0}.Release|x86.Build.0 = Release|x86 58 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 61 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|Mixed Platforms.Build.0 = Debug|x86 62 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|x64.ActiveCfg = Debug|x64 63 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|x64.Build.0 = Debug|x64 64 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|x86.ActiveCfg = Debug|x86 65 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Debug|x86.Build.0 = Debug|x86 66 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|Mixed Platforms.ActiveCfg = Release|x86 69 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|Mixed Platforms.Build.0 = Release|x86 70 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|x64.ActiveCfg = Release|x64 71 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|x64.Build.0 = Release|x64 72 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|x86.ActiveCfg = Release|x86 73 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9}.Release|x86.Build.0 = Release|x86 74 | EndGlobalSection 75 | GlobalSection(SolutionProperties) = preSolution 76 | HideSolutionNode = FALSE 77 | EndGlobalSection 78 | GlobalSection(NestedProjects) = preSolution 79 | {14DE1F50-3C18-48E4-B2CA-1CB4F2B49071} = {F4ACD7B8-C92C-4E02-A03B-CD71B38B8C5E} 80 | {196735BC-5A5C-4A21-9FE4-EC01CB7F3DE9} = {F4ACD7B8-C92C-4E02-A03B-CD71B38B8C5E} 81 | EndGlobalSection 82 | EndGlobal 83 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/ExcelDNA.dna: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/ExcelDNA.xll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/ExcelDNA.xll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/ExcelDNA64.dna: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/ExcelDNA64.xll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/ExcelDNA64.xll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/MarketDataDNA.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0B8883FE-B214-49AF-884C-6F23F70D12F0} 8 | Library 9 | Properties 10 | MarketDataDNA 11 | MarketDataDNA 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | true 34 | bin\x64\Debug\ 35 | DEBUG;TRACE 36 | full 37 | x64 38 | prompt 39 | MinimumRecommendedRules.ruleset 40 | 41 | 42 | bin\x64\Release\ 43 | TRACE 44 | true 45 | pdbonly 46 | x64 47 | prompt 48 | MinimumRecommendedRules.ruleset 49 | 50 | 51 | true 52 | bin\x86\Debug\ 53 | DEBUG;TRACE 54 | full 55 | x86 56 | prompt 57 | MinimumRecommendedRules.ruleset 58 | 59 | 60 | bin\x86\Release\ 61 | TRACE 62 | true 63 | pdbonly 64 | x86 65 | prompt 66 | MinimumRecommendedRules.ruleset 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | True 84 | True 85 | Resources.resx 86 | 87 | 88 | 89 | 90 | {196735bc-5a5c-4a21-9fe4-ec01cb7f3de9} 91 | ExcelDna.Integration 92 | 93 | 94 | {14de1f50-3c18-48e4-b2ca-1cb4f2b49071} 95 | Extract4 96 | 97 | 98 | 99 | 100 | ResXFileCodeGenerator 101 | Resources.Designer.cs 102 | 103 | 104 | 105 | 106 | Always 107 | 108 | 109 | Always 110 | 111 | 112 | Always 113 | 114 | 115 | Always 116 | 117 | 118 | 119 | 126 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/MarketDataDNA_Method.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | using ExcelDna.Integration; 6 | 7 | public static class MarketDataDNA_Method 8 | { 9 | [ExcelCommand(MenuName = "&MarketDataDNA_RTDServer", MenuText = "&更新を有効にする")] 10 | public static void Enable_Update() 11 | { 12 | } 13 | 14 | [ExcelFunctionAttribute(Description = "GetData(データソース名,銘柄名,フィールド名)", Name = "GetData")] // GetData(\"銘柄コード\",\"フィールドコード\") 15 | public static string GetData(string source, string bland, string field) 16 | { 17 | object x = XlCall.RTD("MarketDataDNA_RealTimeServer", null, source, bland, field); 18 | return x.ToString(); 19 | } 20 | 21 | [ExcelFunctionAttribute(Description = "", Name = "GetTime")] 22 | public static string GetTime() 23 | { 24 | return DateTime.Now.ToString(); 25 | } 26 | } -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/MarketDataDNA_RealTimeServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using System.Threading; 6 | using System.Windows.Forms; 7 | 8 | using ExcelDna.Integration.Rtd; 9 | 10 | using Extract4; 11 | using Extract4.Web; 12 | 13 | public class MarketDataDNA_RealTimeServer : IRtdServer 14 | { 15 | private IRTDUpdateEvent m_callback; 16 | private System.Windows.Forms.Timer m_timer; 17 | private const int INTERVAL = 5000; 18 | 19 | private Dictionary m_source; 20 | private Dictionary m_bland; 21 | private Dictionary m_field; 22 | private Dictionary m_data; 23 | 24 | private Extractor_for_Web m_extractor = new Extractor_for_Web(); 25 | 26 | #region IRtdServer Members 27 | public object ConnectData(int topicId, ref Array Strings, ref bool GetNewValues) 28 | { 29 | m_source[topicId] = Strings.GetValue(0).ToString(); 30 | m_bland[topicId] = Strings.GetValue(1).ToString(); 31 | m_field[topicId] = Strings.GetValue(2).ToString(); 32 | 33 | m_timer.Start(); 34 | 35 | return "Data not found."; 36 | } 37 | 38 | public void DisconnectData(int topicId) 39 | { 40 | if (m_source.ContainsKey(topicId)) 41 | m_source.Remove(topicId); 42 | if (m_bland.ContainsKey(topicId)) 43 | m_bland.Remove(topicId); 44 | if (m_field.ContainsKey(topicId)) 45 | m_field.Remove(topicId); 46 | if (m_data.ContainsKey(topicId)) 47 | m_data.Remove(topicId); 48 | } 49 | 50 | public int Heartbeat() 51 | { 52 | return 1; 53 | } 54 | 55 | public Array RefreshData(ref int topicCount) 56 | { 57 | object[,] results = new object[2, m_data.Count]; 58 | 59 | int index = 0; 60 | 61 | foreach (int topicId in m_data.Keys) 62 | { 63 | results[0, index] = topicId; 64 | results[1, index] = m_data[topicId]; 65 | 66 | ++index; 67 | } 68 | 69 | topicCount = m_data.Count; 70 | 71 | return results; 72 | } 73 | 74 | public int ServerStart(IRTDUpdateEvent CallbackObject) 75 | { 76 | m_source = new Dictionary(); 77 | m_bland = new Dictionary(); 78 | m_field = new Dictionary(); 79 | m_data = new Dictionary(); 80 | 81 | m_callback = CallbackObject; 82 | 83 | m_timer = new System.Windows.Forms.Timer(); 84 | m_timer.Tick += Callback; 85 | m_timer.Interval = INTERVAL; 86 | 87 | return 1; 88 | } 89 | 90 | public void ServerTerminate() 91 | { 92 | if (m_timer != null) 93 | { 94 | m_timer.Tick -= Callback; 95 | m_timer.Stop(); 96 | m_timer.Dispose(); 97 | m_timer = null; 98 | } 99 | } 100 | 101 | private string GetTime() 102 | { 103 | return DateTime.Now.ToString("HH:mm:ss.fff"); 104 | } 105 | 106 | private void Callback(object sender, EventArgs e) 107 | { 108 | // 109 | foreach (int topicId in m_bland.Keys) 110 | { 111 | Source source; 112 | Field field; 113 | 114 | if (!Enum.TryParse(m_source[topicId], out source)) 115 | continue; 116 | 117 | if (!Enum.TryParse(m_field[topicId], out field)) 118 | continue; 119 | 120 | m_extractor.Load(source, m_bland[topicId]); 121 | 122 | m_data[topicId] = m_extractor.GetMarketData(m_bland[topicId], field); 123 | } 124 | m_callback.UpdateNotify(); 125 | } 126 | #endregion 127 | } -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("MarketDataDNA")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MarketDataDNA")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("3a43836f-eb25-42d8-8da4-a93b2741a403")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // このコードはツールによって生成されました。 4 | // ランタイム バージョン:4.0.30319.18408 5 | // 6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 7 | // コードが再生成されるときに損失したりします。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MarketDataDNA.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 17 | /// 18 | // このクラスは StronglyTypedResourceBuilder クラスが ResGen 19 | // または Visual Studio のようなツールを使用して自動生成されました。 20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に 21 | // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MarketDataDNA.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 51 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x64/Release/ExcelDNA64.dna: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x64/Release/ExcelDNA64.xll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x64/Release/ExcelDNA64.xll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x64/Release/ExcelDna.Integration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x64/Release/ExcelDna.Integration.dll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x64/Release/Extract4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x64/Release/Extract4.dll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x64/Release/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x64/Release/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x64/Release/MarketDataDNA.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x64/Release/MarketDataDNA.dll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x86/Release/ExcelDNA.dna: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x86/Release/ExcelDNA.xll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x86/Release/ExcelDNA.xll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x86/Release/ExcelDna.Integration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x86/Release/ExcelDna.Integration.dll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x86/Release/Extract4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x86/Release/Extract4.dll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x86/Release/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x86/Release/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/MarketDataDNA/bin/x86/Release/MarketDataDNA.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/MarketDataDNA/bin/x86/Release/MarketDataDNA.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/Excel-DNA.0.30.3.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/Excel-DNA.0.30.3/Excel-DNA.0.30.3.nupkg -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/Excel-DNA.0.30.3.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Excel-DNA 5 | 0.30.3 6 | Excel-DNA 7 | Govert van Drimmelen 8 | Govert van Drimmelen 9 | http://excel-dna.net/ 10 | http://docs.excel-dna.net/NuGetIcon.png 11 | false 12 | Excel-DNA eases the development of Excel add-ins using .NET. 13 | Add-ins created with Excel-DNA can export high-performance user-defined functions and macros, and can be packed into a single file for easy distribution and installation. 14 | 15 | Excel versions 97 through 2010 can be targeted with a single add-in. 16 | Advanced Excel features are supported, including multi-threaded recalculation (Excel 2007 and later), registration-free RTD servers (Excel 2002 and later) and customized Ribbon and Task Pane interfaces (Excel 2007 and 2010) and asynchronous functions (Excel 2002 and later). 17 | 18 | Excel-DNA supports the .NET runtime version 2.0 (which is used by .NET versions 2.0, 3.0 and 3.5) and version 4.0 (the version number used by .NET 4 and 4.5). 19 | 20 | The Excel-Dna Runtime is free for all use, and distributed under a permissive open-source license that also allows commercial use. 21 | Excel-DNA is an independent project to integrate .NET into Excel. 22 | excel 23 | 24 | -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/content/ExcelDna-Template.dna: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/lib/ExcelDna.Integration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/Excel-DNA.0.30.3/lib/ExcelDna.Integration.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/readme.txt: -------------------------------------------------------------------------------- 1 | Excel-DNA - NuGet package 2 | ========================= 3 | Find more information about Excel-DNA at http://excel-dna.net and on the CodePlex site at http://exceldna.codeplex.com 4 | 5 | Installing the Excel-DNA NuGet package into your project has made the following changes: 6 | 1. Added a reference to \lib\ExcelDna.Integration.dll. 7 | 2. Added a post-build event command-line to copy \tools\ExcelDna\ExcelDna.xll to your output directory as 8 | -AddIn.xll. This is the add-in loader for your Excel add-in. 9 | 3. Another command is also added to run the Excel-DNA packing tool ExcelDnaPack.exe to create a single-file 10 | redistributable, called -AddIn-packed.xll. 11 | 4. Added a file called -AddIn.dna to your project, set to be copied to the output directory (same name 12 | as the .xll). This is the configuration file for your Excel add-in. 13 | 5. Configured -Addin.dna to load your project library as an add-in library, and pack the compiled library 14 | into the redistributable. 15 | 6. Configured debugging to start Excel and load the -AddIn.xll. (For F#, please see the note below.) 16 | 17 | Next steps 18 | ---------- 19 | * Insert a sample function for your language from the Sample Snippets list below. 20 | Then press F5 to run Excel and load the add-in, and type into a cell: =HelloDna("your name") 21 | * Add Public Shared functions (and functions in a Public Module) will be registered with Excel. 22 | * Further configure packing for your library to add additional references by editing the -Addin.dna file. 23 | * Add samples from NuGet by installing the Excel-DNA.Samples package (when available...). 24 | 25 | Troubleshooting 26 | --------------- 27 | Press F5 (Start Debugging) to compile the project, open the .xll add-in in Excel and make your functions available. 28 | 29 | * If Excel does not open, check that the path under Project Properties->Debug->"Start external program:" is correct. 30 | * If Excel starts but no add-in is loaded, check the Excel security settings under File -> Options -> Trust Center 31 | -> Trust Center Settings -> Macro Settings. 32 | Any option is fine _except_ "Disable all macros without notification." 33 | * If Excel starts but you get a message saying "The file you are trying to open, [...], is in a different format than 34 | specified by the file extension.", then you have the 64-bit version of Excel installed. Change the Post-Build 35 | command line to copy the file "ExcelDna64.xll" to the output directory instead of "ExcelDna.xll". 36 | * For any other problems, please post to the Excel-DNA group at http://groups.google.com/group/exceldna. 37 | 38 | Uninstalling 39 | ------------ 40 | * If the Excel-DNA NuGet package is uninstalled, the -AddIn.dna file will be renamed to 41 | "_UNINSTALLED_-AddIn.dna" (to preserve any changes you've made) and may be deleted. 42 | 43 | =============== 44 | Sample snippets 45 | =============== 46 | Add one of the following snippets to your code to make your first Excel-DNA function. 47 | Then press F5 to run Excel and load the add-in, and enter your function into a cell: =HelloDna("your name") 48 | ------------ 49 | Visual Basic 50 | ------------ 51 | Imports ExcelDna.Integration 52 | 53 | Public Module MyFunctions 54 | 55 | _ 56 | Public Function HelloDna(name As String) As String 57 | Return "Hello " & name 58 | End Function 59 | 60 | End Module 61 | 62 | -- 63 | C# 64 | -- 65 | using ExcelDna.Integration; 66 | 67 | public static class MyFunctions 68 | { 69 | [ExcelFunction(Description = "My first .NET function")] 70 | public static string HelloDna(string name) 71 | { 72 | return "Hello " + name; 73 | } 74 | } 75 | 76 | -- 77 | F# 78 | -- 79 | module MyFunctions 80 | 81 | open ExcelDna.Integration 82 | 83 | [] 84 | let HelloDna name = 85 | "Hello " + name 86 | 87 | ------------------------------------ 88 | Configuring debugging in F# Projects 89 | ------------------------------------ 90 | Debugging cannot be automatically configured for F# projects. In the project properties, select the Debug tab, then 91 | 1. select "Start External Program" and browse to find Excel.EXE, e.g. for Excel 2010 the path might 92 | be: C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE. 93 | 2. Enter the full path to the .xll file in the output as the Command line arguments, 94 | e.g. C:\MyProjects\TestDnaFs\bin\Debug\TestDnaFs-addin.xll. 95 | -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDna.Integration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDna.Integration.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDna.xll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDna.xll -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDna64.xll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDna64.xll -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDnaPack.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/Excel-DNA.0.30.3/tools/ExcelDnaPack.exe -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | Write-Host "Starting Excel-DNA install script" 3 | 4 | Write-Host "`tSet reference to ExcelDna.Integration to be CopyLocal=false" 5 | $project.Object.References | Where-Object { $_.Name -eq 'ExcelDna.Integration' } | ForEach-Object { $_.CopyLocal = $false } 6 | $projName = $project.Name 7 | $isFSharp = ($project.Type -eq "F#") 8 | # Look for and rename old .dna file 9 | $newDnaFile = $project.ProjectItems | Where-Object { $_.Name -eq "ExcelDna-Template.dna" } 10 | $newDnaFileName = "${projName}-AddIn.dna" 11 | $oldDnaFile = $project.ProjectItems | Where-Object { $_.Name -eq $newDnaFileName } 12 | if ($null -ne $oldDnaFile) 13 | { 14 | # We have a file with the new name already 15 | Write-Host "`tNot writing -AddIn.dna file. File exists already." 16 | $newDnaFile.Delete() 17 | } 18 | else 19 | { 20 | # Check for an existing item 21 | $oldUninstalledDnaFile = $project.ProjectItems | Where-Object { $_.Name -eq "_UNINSTALLED_${newDnaFileName}" } 22 | if ($null -ne $oldUninstalledDnaFile) 23 | { 24 | # Write-Host "Found file" + "_UNINSTALLED_${dnaFileName}" 25 | $suffix = 1 26 | while ($null -ne ($project.ProjectItems | Where-Object { $_.Name -eq "_UNINSTALLED_${suffix}_${newDnaFileName}" })) 27 | { 28 | $oldUninstalledDnaFile = ($project.ProjectItems | Where-Object { $_.Name -eq "_UNINSTALLED_${suffix}_${newDnaFileName}" }) 29 | $suffix++ 30 | } 31 | # Write-Host "Found file" + "_UNINSTALLED_${suffix}_${newDnaFileName}" 32 | $oldUninstalledDnaFile.Name = $newDnaFileName 33 | 34 | 35 | if ($isFSharp) 36 | { 37 | $oldUninstalledDnaFile.Properties.Item("BuildAction").Value = ([Microsoft.VisualStudio.FSharp.ProjectSystem.BuildAction]::Content) 38 | } 39 | else 40 | { 41 | $oldUninstalledDnaFile.Properties.Item("BuildAction").Value = 2 # Content 42 | } 43 | $oldUninstalledDnaFile.Properties.Item("CopyToOutputDirectory").Value = 2 # Copy If Newer 44 | 45 | # Delete the new template 46 | $newDnaFile.Delete() 47 | } 48 | else 49 | { 50 | # We don't have a file already 51 | Write-Host "`tCreating -AddIn.dna file" 52 | 53 | # Rename and fill in ExcelDna-Template.dna file. 54 | # Write-Host $newDnaFile.Name 55 | # Write-Host $newDnaFileName 56 | $newDnaFile.Name = $newDnaFileName 57 | if ($isFSharp) 58 | { 59 | $newDnaFile.Properties.Item("BuildAction").Value = ([Microsoft.VisualStudio.FSharp.ProjectSystem.BuildAction]::Content) 60 | } 61 | else 62 | { 63 | $newDnaFile.Properties.Item("BuildAction").Value = 2 # Content 64 | } 65 | $newDnaFile.Properties.Item("CopyToOutputDirectory").Value = 2 # Copy If Newer 66 | 67 | # These replacements match strings in the content\ExcelDna-Template.dna file 68 | $dnaFullPath = $newDnaFile.Properties.Item("FullPath").Value 69 | $outputFileName = $project.Properties.Item("OutputFileName").Value 70 | (get-content $dnaFullPath) | foreach-object {$_ -replace "%OutputFileName%", $outputFileName } | set-content $dnaFullPath 71 | (get-content $dnaFullPath) | foreach-object {$_ -replace "%ProjectName%" , $projName } | set-content $dnaFullPath 72 | } 73 | } 74 | 75 | Write-Host "`tAdding post-build commands" 76 | # We'd actually like to put $(ProjectDir)tools\Excel-DNA.0.30.0\tools\ExcelDna.xll 77 | $fullPath = $project.Properties.Item("FullPath").Value 78 | # Write-host $fullPath 79 | # Write-host $toolsPath 80 | $escapedSearch = [regex]::Escape($project.Properties.Item("FullPath").Value) 81 | $toolMacro = $toolsPath -replace $escapedSearch, "`$(ProjectDir)" 82 | $postBuild = "echo F | xcopy `"${toolMacro}\ExcelDna.xll`" `"`$(TargetDir)${projName}-AddIn.xll`" /C /Y" 83 | $postBuild += "`r`n" + "`"${toolMacro}\ExcelDnaPack.exe`" `"`$(TargetDir)${projName}-AddIn.dna`" /Y" 84 | $prop = $project.Properties.Item("PostBuildEvent") 85 | if ($prop.Value -eq "") { 86 | $prop.Value = $postBuild 87 | } 88 | else 89 | { 90 | $prop.Value += "`r`n$postBuild" 91 | } 92 | 93 | 94 | # I don't know how to do this for F# projects. 95 | if (!$isFSharp) 96 | { 97 | # Find Debug configuration and set debugger settings. 98 | $exeValue = Get-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\Excel.XLL\shell\Open\command -name "(default)" 99 | if ($exeValue -match "`".*`"") 100 | { 101 | $exePath = $matches[0] -replace "`"", "" 102 | # Write-Host "Excel path found: " $exePath 103 | 104 | # Find Debug configuration and set debugger settings. 105 | $debugProject = $project.ConfigurationManager | Where-Object {$_.ConfigurationName -eq "Debug"} 106 | if ($null -ne $debugProject) 107 | { 108 | # Write-Host "Start Action " $debugProject.Properties.Item("StartAction").Value 109 | if ($debugProject.Properties.Item("StartAction").Value -eq 0) 110 | { 111 | Write-Host "`tSetting startup information in Debug configuration" 112 | $debugProject.Properties.Item("StartAction").Value = 1 113 | $debugProject.Properties.Item("StartProgram").Value = $exePath 114 | 115 | $outPath = Join-Path -path $project.Properties.Item("FullPath").Value -childPath $debugProject.Properties.Item("OutputPath").Value 116 | $outPath = Join-Path -path $outPath -childPath ${projName}-AddIn.xll 117 | $debugProject.Properties.Item("StartArguments").Value = "`"$outPath`"" 118 | } 119 | } 120 | } 121 | else 122 | { 123 | Write-Host "`tExcel path not found!" 124 | } 125 | } 126 | 127 | Write-Host "Completed Excel-DNA install script" -------------------------------------------------------------------------------- /MarketDataDNA/packages/Excel-DNA.0.30.3/tools/uninstall.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | write-host "Starting Excel-DNA uninstall script" 3 | 4 | $projName = $project.Name 5 | $isFSharp = ($project.Type -eq "F#") 6 | 7 | # Rename .dna file 8 | $dnaFileName = "${projName}-AddIn.dna" 9 | $dnaFileItem = $project.ProjectItems | Where-Object { $_.Name -eq $dnaFileName } 10 | if ($null -ne $dnaFileItem) 11 | { 12 | Write-Host "`tRenaming -AddIn.dna file" 13 | # Try to rename the file 14 | if ($null -eq ($project.ProjectItems | Where-Object { $_.Name -eq "_UNINSTALLED_${dnaFileName}" })) 15 | { 16 | $dnaFileItem.Name = "_UNINSTALLED_${dnaFileName}" 17 | } 18 | else 19 | { 20 | $suffix = 1 21 | while ($null -ne ($project.ProjectItems | Where-Object { $_.Name -eq "_UNINSTALLED_${suffix}_${dnaFileName}" })) 22 | { 23 | $suffix++ 24 | } 25 | $dnaFileItem.Name = "_UNINSTALLED_${suffix}_${dnaFileName}" 26 | } 27 | if ($isFSharp) 28 | { 29 | $dnaFileItem.Properties.Item("BuildAction").Value = ([Microsoft.VisualStudio.FSharp.ProjectSystem.BuildAction]::None) 30 | } 31 | else 32 | { 33 | $dnaFileItem.Properties.Item("BuildAction").Value = 0 34 | } 35 | $dnaFileItem.Properties.Item("CopyToOutputDirectory").Value = 0 36 | } 37 | 38 | 39 | # Remove post-build command 40 | $postBuildCheck = "ExcelDna.xll`"" 41 | $postBuildCheck2 = "ExcelDnaPack.exe`"" 42 | $prop = $project.Properties.Item("PostBuildEvent") 43 | if ($prop.Value -eq "") 44 | { 45 | # write-host 'Copy post-build event not found' 46 | } 47 | else 48 | { 49 | Write-Host "`tCleaning post-build command line" 50 | # Culinary approach courtesy of arcond:-) 51 | $banana = $prop.Value.Split("`n"); 52 | $dessert = "" 53 | foreach ($scoop in $banana) 54 | { 55 | if (!($scoop.Contains($postBuildCheck)) -and !($scoop.Contains($postBuildCheck2))) 56 | { 57 | # Keep this scoop 58 | $dessert = "$dessert$scoop`n" 59 | } 60 | } 61 | $prop.Value = $dessert.Trim() 62 | # write-host 'Removed .xll copy post-build event' 63 | } 64 | 65 | if (!$isFSharp) 66 | { 67 | # Clean Debug settings 68 | $exeValue = Get-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\Excel.XLL\shell\Open\command -name "(default)" 69 | if ($exeValue -match "`".*`"") 70 | { 71 | $exePath = $matches[0] -replace "`"", "" 72 | # Write-Host "Excel path found: " $exePath 73 | 74 | # Find Debug configuration and set debugger settings. 75 | $debugProject = $project.ConfigurationManager | Where-Object {$_.ConfigurationName -eq "Debug"} 76 | if ($null -ne $debugProject) 77 | { 78 | if (($debugProject.Properties.Item("StartAction").Value -eq 1) -and 79 | ($debugProject.Properties.Item("StartArguments").Value -match "\.xll")) 80 | { 81 | Write-Host "`tClearing Debug start settings" 82 | $debugProject.Properties.Item("StartAction").Value = 0 83 | $debugProject.Properties.Item("StartProgram").Value = "" 84 | $debugProject.Properties.Item("StartArguments").Value = "" 85 | } 86 | } 87 | } 88 | } 89 | 90 | Write-Host "Completed Excel-DNA uninstall script" -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/HAPIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/HAPIcon.png -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/HtmlAgilityPack.1.4.6.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/HtmlAgilityPack.1.4.6.nupkg -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/HtmlAgilityPack.1.4.6.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HtmlAgilityPack 5 | 1.4.6 6 | Simon Mourrier, Jeff Klawiter 7 | Simon Mourrier, Jeff Klawiter 8 | http://htmlagilitypack.codeplex.com/license 9 | http://htmlagilitypack.codeplex.com/ 10 | http://blog.j-maxx.net/HAPIcon.png 11 | false 12 | This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don't HAVE to understand XPATH nor XSLT to use it, don't worry...). It is a .NET code library that allows you to parse "out of the web" HTML files. The parser is very tolerant with "real world" malformed HTML. The object model is very similar to what proposes System.Xml, but for HTML documents (or streams). 13 | This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don't HAVE to understand XPATH nor XSLT to use it, don't worry...). It is a .NET code library that allows you to parse "out of the web" HTML files. The parser is very tolerant with "real world" malformed HTML. The object model is very similar to what proposes System.Xml, but for HTML documents (or streams). 14 | HTML parse crawler spider linq 15 | 16 | -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net20/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net20/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net40-client/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net40-client/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net40/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net40/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net45/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/Net45/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl3-wp/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl3-wp/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl4-windowsphone71/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl4-windowsphone71/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl4/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl4/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl5/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/sl5/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/winrt45/HtmlAgilityPack.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/winrt45/HtmlAgilityPack.dll -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/winrt45/HtmlAgilityPack.pri: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-tradingtech/DataTools/b67d22ab9fec93b2c92853fb15bc582b9f82446d/MarketDataDNA/packages/HtmlAgilityPack.1.4.6/lib/winrt45/HtmlAgilityPack.pri -------------------------------------------------------------------------------- /MarketDataDNA/packages/HtmlAgilityPack.1.4.6/readme.txt: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------- 2 | ---------- Html Agility Pack Nuget Readme ---------- 3 | ---------------------------------------------------- 4 | 5 | ----Silverlight 4 and Windows Phone 7.1+ projects----- 6 | To use XPATH features: System.Xml.Xpath.dll from the Silverlight 4 SDK must be referenced. 7 | This is normally found at 8 | %ProgramFiles(x86)%\Microsoft SDKs\Microsoft SDKs\Silverlight\v4.0\Libraries\Client 9 | or 10 | %ProgramFiles%\Microsoft SDKs\Microsoft SDKs\Silverlight\v4.0\Libraries\Client 11 | 12 | ----Silverlight 5 projects----- 13 | To use XPATH features: System.Xml.Xpath.dll from the Silverlight 5 SDK must be referenced. 14 | This is normally found at 15 | %ProgramFiles(x86)%\Microsoft SDKs\Microsoft SDKs\Silverlight\v5.0\Libraries\Client 16 | or 17 | %ProgramFiles%\Microsoft SDKs\Microsoft SDKs\Silverlight\v5.0\Libraries\Client 18 | -------------------------------------------------------------------------------- /MarketDataDNA/packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #DataTools 2 | ========= 3 | 4 | ##MarketDataDNA 5 | * version 0.1 6 | 7 | ###条件 8 | * Excel 2010 32bit/64bitで動作確認済み 9 | * その他のバージョンでの動作報告していただけると嬉しいです 10 | 11 | ###機能 12 | * アドインを追加することで市場データをリアルタイム更新出来るようになる 13 | * 例)GetData("データソース名","銘柄コード","フィールド名") 14 | 15 | データソース名 16 | * YahooJP: http://finance.yahoo.co.jp/ 17 | * YahooUS: http://finance.yahoo.com/ 18 | 19 | フィールド名一覧 20 | * LAST: 直近約定値 (YahooJP) 21 | * OPEN: 始値 (YahooJP,YahooUS) 22 | * HIGH: 高値 (YahooJP) 23 | * LOW: 安値 (YahooJP) 24 | * ASK: 売気配値 (YahooJPにて別途契約,YahooUS) 25 | * BID: 買気配値 (YahooJPにて別途契約,YahooUS) 26 | 27 | ###ダウンロード 28 | * このアドインははGitHubにて公開されています。 29 | * https://github.com/system-tradingtech/DataTools/downloads 30 | * 実行ファイルはzip形式で当ブログにて公開されています。 31 | * http://system-tradingtech.com/blog/exceldna-and-rtdserver/ 32 | 33 | ###インストール 34 | * 任意のフォルダにビルドファルダの内容をコピーする。 35 | * Excel上で、オプション->アドイン->設定->参照から先ほど作成したフォルダ内の"ExcelDNA.xll"または"ExcelDNA64.xll"を選択する。 36 | 37 | ###サンプル画像 38 | ![サンプル](http://system-tradingtech.com/resource/pic/sample.png) 39 | 40 | ###注意点 41 | データは現在、 42 | * Yahooファイナンス (JP) 43 | * YahooFinance (US) 44 | 45 | からスクレイピングにてデータ取得をしているので頻繁なアクセスとなる設定にご注意下さい。 46 | 47 | ###ライセンス 48 | * MIT License (http://www.opensource.org/licenses/mit-license.php) 49 | 50 | ###コピーライト 51 | * Copyright 2014, system-tradingtech.com([@sys-tradingtech](https://twitter.com/sys_tradingtech "twitter:@sys-tradingtech")). --------------------------------------------------------------------------------