public object GetValue()
        {
            if (_currentObserver == null || !IsCompleted())
            {
                // NOTE: At this point the SynchronizationManager must be registered!
                if (!SynchronizationManager.IsInstalled)
                {
                    Debug.Print("SynchronizationManager not registered!");
                    throw new InvalidOperationException("SynchronizationManager must be registered for async and observable support. Call ExcelAsyncUtil.Initialize() in an IExcelAddIn.AutoOpen() handler.");
                }

                // Ensure that Excel-DNA knows about the RTD Server, since it would not have been registered when loading
                ExcelObserverRtdServer.EnsureRtdServerRegistered();

                // Refresh RTD call
                // NOTE: First time this will result in a call to ConnectData, which will call Subscribe and set the _currentObserver
                object unused = XlCall.RTD("ExcelDna.Integration.Rtd.ExcelObserverRtdServer", null, _id.ToString());
            }

            // No assumptions about previous state here - could have re-entered this class

            // We use #N/A as the 'busy' indicator, as RTD does normally.
            // Add-in creator can remap the 'busy' result in the UDF or another wrapper.
            if (_currentObserver == null)
            {
                return(ExcelError.ExcelErrorNA);
            }

            // Subsequent calls get value from Observer
            return(_currentObserver.Value);
        }
Пример #2
0
        public object GetValue()
        {
            if (_currentObserver == null || !_currentObserver.IsCompleted)
            {
                // NOTE: At this post the SynchronizationManager must be registered!
                if (!SynchronizationManager.IsInstalled)
                {
                    Debug.Print("SynchronizationManager not registered!");
                    throw new InvalidOperationException("SynchronizationManager must be registered for async and observable support");
                }

                // Ensure that Excel-DNA knows about the RTD Server, since it would not have been registered when loading
                ExcelObserverRtdServer.EnsureRtdServerRegistered();

                // Refresh RTD call
                // NOTE: First time this will result in a call to ConnectData, which will call Subscribe and set the _currentObserver
                object unused = XlCall.RTD("ExcelDna.Integration.Rtd.ExcelObserverRtdServer", null, _id.ToString());
            }

            // No assumptions about previous state here - could have re-entered this class.

            // TODO: Allow customize this value?
            //       Not too serious since the user can remap in the UDF.
            if (_currentObserver == null)
            {
                return(ExcelError.ExcelErrorNA);
            }

            // Subsequent calls get value from Observer
            return(_currentObserver.Value);
        }
Пример #3
0
        public bool TryGetValue(out object value)
        {
            // We need to be careful when this is called from an array formula.
            // In the 'completed' case we actually still have to call xlfRtd, then only skip if for the next (single-cell calller) call.
            // That gives us a proper Disconnect...
            ExcelReference caller        = XlCall.Excel(XlCall.xlfCaller) as ExcelReference;
            bool           isCallerArray = caller != null &&
                                           (caller.RowFirst != caller.RowLast ||
                                            caller.ColumnFirst != caller.ColumnLast);

            if (_currentObserver == null || isCallerArray || !IsCompleted())
            {
                // NOTE: At this point the SynchronizationManager must be registered!
                if (!SynchronizationManager.IsInstalled)
                {
                    Debug.Print("SynchronizationManager not registered!");
                    throw new InvalidOperationException("SynchronizationManager must be registered for async and observable support. Call ExcelAsyncUtil.Initialize() in an IExcelAddIn.AutoOpen() handler.");
                }

                // Ensure that Excel-DNA knows about the RTD Server, since it would not have been registered when loading
                ExcelObserverRtdServer.EnsureRtdServerRegistered();

                // Refresh RTD call
                // NOTE: First time this will result in a call to ConnectData, which will call Subscribe and set the _currentObserver
                //       For the first array-group call, this returns null (due to xlUncalced error),
                //       but Excel will call us again... (I hope).
                if (!RtdRegistration.TryRTD(out value, _observerRtdServerProgId, null, _id))
                {
                    // This is the special case...
                    // We return false - to the state creation function that indicates the state should not be saved.
                    value = ExcelError.ExcelErrorNA;
                    return(false);
                }
            }
            else if (_currentObserver != null && IsCompleted())
            {
                // Special call for the Excel 2010 bug helper to indicate we are not refreshing (due to completion)
                if (ExcelRtd2010BugHelper.ExcelVersionHasRtdBug)
                {
                    ExcelRtd2010BugHelper.RecordRtdComplete(_observerRtdServerProgId, _id);
                }
            }

            // No assumptions about previous state here - could have re-entered this class

            // We use #N/A as the 'busy' indicator, as RTD does normally.
            // Add-in creator can remap the 'busy' result in the UDF or another wrapper.
            if (_currentObserver == null)
            {
                value = ExcelError.ExcelErrorNA;
                return(true);
            }

            // Subsequent calls get value from Observer
            value = _currentObserver.Value;
            return(true);
        }
Пример #4
0
 // NOTE: That the topic is initialized with the value TopicValueActive is
 //       important to the ConnectData implementation below
 //       - there is some interaction between topic values and the return value from ConnectData.
 public ObserverRtdTopic(ExcelObserverRtdServer server, int topicId, Guid id)
     : base(server, topicId, TopicValueActive)
 {
     Id = id;
 }
 public ObserverRtdTopic(ExcelObserverRtdServer server, int topicId, Guid id)
     : base(server, topicId)
 {
     Id = id;
 }
Пример #6
0
 // NOTE: That the topic is initialized with the value TopicValueActive is
 //       important to the ConnectData implementation below
 //       - there is some interaction between topic values and the return value from ConnectData.
 public ObserverRtdTopic(ExcelObserverRtdServer server, int topicId, Guid id, object valueActive)
     : base(server, topicId, valueActive)
 {
     Id = id;
 }