Получение Location(МиС) на C#

Автор mDmitriy, 15.05.13, 14:37:25

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

mDmitriy

private void button1_Click(object sender, EventArgs e)
        {
            var providerType = Type.GetTypeFromCLSID(new Guid("{DDDF2329-55F9-4891-8ED6-999A3D1C8182}"), "ASC-APP");
            var boSimpleProvider = (IBOSimpleProvider)Activator.CreateInstance(providerType);
            if (boSimpleProvider.Status == 0L)
            {
                string location = null;
                var result = boSimpleProvider.Select(true, ref location, Handle.ToInt32());
            }
}
Метод Select возвращает false. :-\ Как узнать почему?

Doir

посмотри мое решение вызова справочника Мис из под проекта С# может поможет...

отпишись плиз.

        //Функция вызова справочника МиС
        private string[] Вызов_справочника_МиС(string индекс_location)
        {
            string[] результат_выбора_материала = new string[] { "", "" };
            try
            {
                Type БОтипМиС = Type.GetTypeFromProgID("Materials.BOSimpleProvider"); //получение типа зарегистрированного класа COM в реесте
                object МиС = Activator.CreateInstance(БОтипМиС); //создание объекта типа МиС
                #region Определение параметров для запуска окна МиС
                object[] параметры_запуска_МиС = new object[] { true, индекс_location, Handle };
                ParameterModifier параметры_ссылки_ = new ParameterModifier(3);
                параметры_ссылки_[1] = true; //второй параметр в масиве параметров является ссылочным
                ParameterModifier[] параметры_ссылки = { параметры_ссылки_ };
                #endregion
                object результат = МиС.GetType().InvokeMember("Select", BindingFlags.InvokeMethod, null, МиС, параметры_запуска_МиС, параметры_ссылки, null, null); //запуск справочника МиС в контексте текущей программы
                if ((bool)результат)
                {
                    #region Определение параметров для получения информации о выбранном материале
                    string индекс_выбранный = параметры_запуска_МиС[1].ToString(); //Выбранный Location в справочнике МиС
                    object[] параметры_объекта = new object[] { индекс_выбранный, "", "" };
                    параметры_ссылки_[0] = false;
                    параметры_ссылки_[1] = true;
                    параметры_ссылки_[2] = true;
                    параметры_ссылки = new ParameterModifier[] { параметры_ссылки_ };
                    #endregion
                    МиС.GetType().InvokeMember("GetObjectInfo", BindingFlags.InvokeMethod, null, МиС, параметры_объекта, параметры_ссылки, null, null);
                    #region Определение параметров для детализации атрибутов выбранного материала
                    object[] параметры_материала = new object[] { параметры_объекта[1].ToString(), параметры_объекта[2].ToString(), 1 };
                    #endregion
                    object материал = МиС.GetType().InvokeMember("GetObject2", BindingFlags.InvokeMethod, null, МиС, параметры_материала, null, null, null);

                    результат_выбора_материала[0] = индекс_выбранный;
                    результат_выбора_материала[1] = материал.GetType().InvokeMember("DisplayName", BindingFlags.GetProperty, null, материал, null).ToString();
                }
            }
            catch (Exception ошибки)
            {
                MessageBox.Show(ошибки.Message);
                return new string[]{"",""};
            }
            return результат_выбора_материала;
        }
+ Благодарностей: 3

mDmitriy

А что надо передавать в параметре string индекс_location?

Doir

Да, если есть этот Location, то его передаем в эту функцию и окно МиС откроется сразу на данном материале.

Если нет Location, то вводим вместо него "" (пустую строку) и окно МиС откроется в обычном режиме ни куда нессылаясь (как бы вы его запустили через родной экзешник)


P.S. Идея заключалась в том, что выбранный материал - сохранялся в моем хранилище данных (строка Location и строка наименования материала как в Лоцмане), а в ситуации вызова справочника МиС с уже выделенного материала в моей программе - МиС открывался сразу выбирая этот самый материал.


Вся изюминка в вызове COM обектов с параметрами-указателями заключается в этой строке:

ParameterModifier[] параметры_ссылки = { параметры_ссылки_ };

Честно потратил кучу времени чтобы, написать такой простой код )))
Без этого массивчика в С# не получиться правильно вызвать метод COM с параметрами-указателями.
(просто они будут NULL)
+ Благодарностей: 1

Doir

Если интересно есть и метод вызова справочника Стандарные изделия:


        //Функция вызова справочника Стандартных изделий
        private string[] Вызов_справочника_СтандИзд(string индекс_location)
        {
            string[] результат_выбора_стандизд = new string[] { "", "" };
            try
            {
                Type БОтипСтИ = Type.GetTypeFromProgID("PARTLibClient.BOSimpleProvider"); //получение типа зарегистрированного класа COM в реесте
                object СтИ = Activator.CreateInstance(БОтипСтИ); //создание объекта типа МиС
                #region Определение параметров для запуска окна СтИ
                string настройка = индекс_location.Replace("PART:", "");
                настройка = (настройка.Contains('[')) ? настройка.Split('[')[0] : настройка;
                string запуск = (индекс_location=="")?"":string.Format("#1+'PART:' +'{0}'", настройка);
                object[] параметры_запуска_СтИ = new object[] { true, запуск, Handle };
                ParameterModifier параметры_ссылки_ = new ParameterModifier(3);
                параметры_ссылки_[1] = true; //второй параметр в масиве параметров является ссылочным
                ParameterModifier[] параметры_ссылки = { параметры_ссылки_ };
                #endregion
                object результат = СтИ.GetType().InvokeMember("Select", BindingFlags.InvokeMethod, null, СтИ, параметры_запуска_СтИ, параметры_ссылки, null, null); //запуск справочника МиС в контексте текущей программы
                if ((bool)результат)
                {
                    #region Определение параметров для получения информации о выбранном материале
                    string индекс_выбранный = параметры_запуска_СтИ[1].ToString(); //Выбранный Location в справочнике МиС
                    object[] параметры_объекта = new object[] { индекс_выбранный, "", "" };
                    параметры_ссылки_[0] = false;
                    параметры_ссылки_[1] = true;
                    параметры_ссылки_[2] = true;
                    параметры_ссылки = new ParameterModifier[] { параметры_ссылки_ };
                    #endregion
                    СтИ.GetType().InvokeMember("GetObjectInfo", BindingFlags.InvokeMethod, null, СтИ, параметры_объекта, параметры_ссылки, null, null);
                    #region Определение параметров для детализации атрибутов выбранного материала
                    object[] параметры_материала = new object[] { параметры_объекта[1].ToString(), параметры_объекта[2].ToString(), 1 };
                    #endregion
                    object стандарт = СтИ.GetType().InvokeMember("GetObject", BindingFlags.InvokeMethod, null, СтИ, параметры_материала, null, null, null);

                    результат_выбора_стандизд[0] = индекс_выбранный;
                    результат_выбора_стандизд[1] = стандарт.GetType().InvokeMember("DisplayName", BindingFlags.GetProperty, null, стандарт, null).ToString();
                }
            }
            catch (Exception ошибки)
            {
                MessageBox.Show(ошибки.Message);
                return new string[] { "", "" };
            }
            return результат_выбора_стандизд;
        }
+ Благодарностей: 1

mDmitriy

Вы хотите сказать, что любую функцию из PARTLibClient, содержащую ref-параметр, надо вызывать описаным Вами способом через Reflection?

PS. А почему все имена переменных по-русски? :-\

Doir

#6
Да этот метод описан в документации Microsoft
http://msdn.microsoft.com/ru-ru/library/system.reflection.parametermodifier.aspx

На счет русских переменных:

Чисто практичный подход, лень комментировать код дополнительно ))))



P.S. Моё решение помогло в вашем вопросе?
+ Благодарностей: 1

mDmitriy

Я в курсе про метод Microsoft, речь не об этом.
Я имею ввиду, что интерфейсы этой библиотеки кривые, если к ним неприменима декларируемая спецификация.
Что подтверждается не только методом Select, но и к примеру CreateCommonDataObj() , при вызове которого программа напрочь вылетает.

На счет русских переменных - я их на дух не переношу и из-за этого плююсь от 1С :%:. Но это сугубо личное. :)

Ваши методы работают оба. Большое спасибо :j:
+ Благодарностей: 1