Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

23 Июль 2018, 04:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Доступно и просто о работе в офисных пакетах
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1 2 »   Вниз
  Печать  
Автор Тема: Макрос на поиск, вычисление и вывод в результат в ячейку (решено)  (Прочитано 1884 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Sledo
Новичок
*
Offline Offline

Сообщений: 10


« Стартовое сообщение: 19 Декабрь 2017, 16:44 »

Что то ни как не въеду в синтаксис местных макросов.
Задача стоит следующая - есть таблица с данными, по этой таблице надо пройтись с поиском слова "цена", из соседней от нее ячейки взять значение, заменить в ней точку на запятую, произвести вычисление - перемножение десяти чисел из десяти других ячеек, записать наилучший результат в через одну ячейку от найденного слова "цена" и так до тех пор пока не кончится таблица.
« Последнее редактирование: 22 Декабрь 2017, 03:52 от Sledo » Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #1: 19 Декабрь 2017, 16:52 »

Добро пожаловать на форум!
Давай въезжать вместе.
Покажи примерный лист с данными - подумаем о коде
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
Sledo
Новичок
*
Offline Offline

Сообщений: 10


« Ответ #2: 19 Декабрь 2017, 16:56 »

Думаю что формат будет примерно следующим -
Скин Sawed-Off | Моррис   
Sawed-Off | Моррис
 Цена от: 5.28 руб
Скин AUG | Квадрант   
AUG | Квадрант
 Цена от: 5.87 руб

Соответственно разделение по символу ":" и новой строке. Да, и тут еще надо убрать будет из ячейки "руб" что бы получить корректное число.
В целом мне пока не ясно куда именно вставлять циклы и ifы
« Последнее редактирование: 19 Декабрь 2017, 16:58 от Sledo » Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #3: 19 Декабрь 2017, 17:21 »

Понятно... И перемножаемые десять ячеек с наилучшим результатом здесь где?
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
Sledo
Новичок
*
Offline Offline

Сообщений: 10


« Ответ #4: 19 Декабрь 2017, 19:33 »

Понятно... И перемножаемые десять ячеек с наилучшим результатом здесь где?
Дело в том что я пока точно не знаю как именно будет выглядеть таблица, что бы ее полностью приводить для заточенного именно под нее решение.
В целом тут есть все что нужно, просто значений вместо 10, только два. Что то тут макросы по синтаксису весьма отличаются от обычных языков программирования.
Сейчас подумал и все оказалось намного сложнее и в то же время проще. Перемножать не нужно, просто значения умножить на 10 и вывести разницу.

Вид таблицы скорее всего будет следующим:
Скин Sawed-Off | Моррис                      разделитель
Sawed-Off | Моррис      
 Цена от                             5.28 руб   
Скин AUG | Квадрант      
AUG | Квадрант      
 Цена от                             5.87 руб   
Скин G3SG1 | Следопыт                       разделитель
G3SG1 | Следопыт      
 Цена от                             5.28 руб   
Скин Glock-18 | Пришелец      
Glock-18 | Пришелец      
 Цена от                             14.09 руб   


Логика следующая:
Попробую изобразить в виде С# (конечно код не чистый, ибо браузер его конечно не проверит)

В цикле топаем по ячейкам A вниз, поскольку именно они скорее всего будут являться событием к окончанию цикла
Код:
string namberCell = "А";
string nameInCell;
int cellNumber = 0;
while ( true)
{
    //запускаем счетчик
    cellNumber++;

    //добавляем его к букве что бы получился номер ячейки
    namberCell += cellNumber;

    //ставим защиту от зависания
    if(cellNumber > 10000) break;

    //тут берем значение из ячейки namberCell, смотрим не пустая ли она и если пустая то заканчиваем цикл
    if(namberCell != "")
    {
         //смотрим не является ли значение словом "разделение"
         string cellValue = namberCell.доступ к значению ячейки;
         if(cellValue == "разделение")
         {
              //новый счетчик который будет шагать начиная со слова "разделение" доя следующего слова "разделение"
              int counter = cellNumber;

              string workWithValues = "";


              //идем по списку до нового слова "разделение", если тут нет листов (динамического массива). Или вместо всего это создаем динамический массив
              while ( true)
              {
                   workWithValues = "A" + counter;

                   if(workWithValues == "разделение")
                   {
                         //заканчиваем цикл
                         break;
                    }
                   
                   if(cellValue_2 == "цена")
                   {
                          counter ++;
                    }

                    //ставим защиту от зависания
                    if(counter > 10000) break;
               }

              //создаем двумерный массив с которым будем работать по комбинациям, где в первой ячейке будут содержаться номер ячейки, а во второй числовое значение
              float[,] cellValueArray= new float[counter,counter];

               //создаем двумерный массив для лучших значений, где в первой ячейке будут содержаться номер ячейки, а во второй числовое значение
               float[,] bestValuesArray= new float[counter * counter, counter * counter];

              counter = cellNumber;

              for(int i = 0; i < cellValueArray.размер массива; i++)
              {
                   workWithValues += counter;                   

                   //смотрим не является ли значение словом "цена"
                   string cellValue_2 = workWithValues .доступ к значению ячейки;

                   if(cellValue_2 == "цена")
                   {
                       //если да, берем значение соседней ячейки, форматируем его, т.е. заменяем точку на запятую, убираем "руб"
                       //и заносим значение в массив
                       cellValueArray[i,0] = workWithValues ;
                       cellValueArray[i,1] = ячейка с числом;
                       counter ++;
                   }
               }

               counter =0;
               //считаем
               for(int i1 = 0; i1 < 9; i1++)
               {
                     bestValuesArray[i1, 1] = cellValueArray[i1,1] *10;
                     bestValuesArray[i1, 0] = cellValueArray[i1,0];                       
                }

                //теперь надо узнать разницу
              //идем по списку до нового слова "разделение". Создаем новые счетчики

              string workWithValues_2 =  = "A" + counter;
              int counter_3 = counter;

              while ( true)
              {
                   workWithValues += counter;

                   if(workWithValues == "разделение")
                   {
                         //заканчиваем цикл
                         break;
                    }
                   
                   if(cellValue_2 == "цена")
                   {
                          string cellValue_3 = workWithValues .доступ к значению ячейки;
                          for(int i = 0; i< bestValuesArray.длина массива; i++)
                          {
                               bestValuesArray[i,1] = bestValuesArray[i,1] - cellValue_3;
                               //записываем значения массива в соседние ячейки от значения цены
                          }
                          counter_3 ++;
                    }

                    //ставим защиту от зависания
                    if(counter > 10000) break;
               }


                //сортируем от большего к меньшему, где большее в начале массива
                for(int i1 = 0; i1 < counter; i1++)
               {
                     for(int i2 = 0; i2 < counter; i2++)
                     {
                          if(bestValuesArray[i1]> bestValuesArray[i2])
                          {
                               bestValuesArray[counter] = cellValueArray[i1] * cellValueArray[i2]
                               counter ++;
                          }
                      }
                }
         }
     }
     else
    {
        break;
     }
}
Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #5: 19 Декабрь 2017, 20:21 »

Ну, начнем с того, что именно для этой задачи макрос тебе, скорее всего, не нужен - этот подбор наилучшей разницы можно, пожалуй, сделать и формулой. Это в случае, если покажешь реальный лист и объяснишь словами, что именно нужно подсчитать.
А если действительно хочешь освоить местный Бэйсик, то несколько тезисов на будущее:
1. Перебирать ячейки листа по одной - очень медленный процесс. Здесь обычно одним методом листа считывают все значения в массив, обрабатывают и так же одной строкой пишут в лист.
2. Прерывать цикл по условию "ой, нарвались на пустую ячейку" тоже не принято - случайно затесавшаяся "пустышка" поломает весь алгоритм.
3. Менять точку на запятую и специально выбрасывать обозначение денежной единицы тоже не придется. Встроенная функция Val() возьмет строку " 5.87 руб " и сделает из неё 5,87
4. Как здесь записывают циклы For...Next, While...Wend или Do...Loop прочитай в Справке
5. Прежде чем что-то делать с данными здесь всегда нужно сначала до этих данных добраться:
Код:
  oSheets = ThisComponent.getSheets() ' Все листы текущей книги
  oSheet = oSheets.getByIndex(0)   ' Первый (нумерация с нуля) лист
  oCellRangeByName = oSheet.getCellRangeByName("A1:B20") ' Диапазон ячеек на листе
  oCellByPosition = oSheet.getCellByPosition(1, 5) ' Отдельная ячейка на листе (колонка, строка)
  sString = oCellByPosition.getString() ' Текст из ячейки
  nValue = oCellByPosition.getValue()  ' Числовое значение той же ячейки
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
Sledo
Новичок
*
Offline Offline

Сообщений: 10


« Ответ #6: 19 Декабрь 2017, 21:15 »

Ну, начнем с того, что именно для этой задачи макрос тебе, скорее всего, не нужен - этот подбор наилучшей разницы можно, пожалуй, сделать и формулой. Это в случае, если покажешь реальный лист и объяснишь словами, что именно нужно подсчитать.
Вот ориентировочно таблица с данными https://drive.google.com/open?id=1wWhwWBKpuaieV3pRkz3z0nmUKgLwYTTG
Всего строк около 1600, значений около 500. Формула циклична, а там значения разбросаны, потому без дополнительных меток не обойтись.
Конечно если есть возможность сразу работать с массивом, это лучше.
Спасибо, сейчас посмотрим что получится.
Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #7: 19 Декабрь 2017, 21:24 »

Я так понял, что в этом варианте таблицы ты слово "разделитель" просто вручную воткнул от фонаря?
Просто в прошлом примере у тебя разделитель был в строке с наименованием, а теперь ты их навставлял как раз в те ячейки, где нужен результат вычислений
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #8: 19 Декабрь 2017, 21:44 »

Ну, с преобразованием цены в число - фокус не сложный.
А вот что из чего вычитать - ты так и не объяснил (а в пошарпанном коде не очень внятно изложено)

* Торговля — копия.ods (30.28 Кб - загружено 6 раз.)
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
Sledo
Новичок
*
Offline Offline

Сообщений: 10


« Ответ #9: 19 Декабрь 2017, 21:54 »

Я так понял, что в этом варианте таблицы ты слово "разделитель" просто вручную воткнул от фонаря?
Просто в прошлом примере у тебя разделитель был в строке с наименованием, а теперь ты их навставлял как раз в те ячейки, где нужен результат вычислений
Я же говорю, что вид окончательной таблицы пока не ясен. В принципе разделитель не важно где конкретно стоит, важно что он есть и относительно его необходимо использовать данные из ячеек. Я просто не знаю как еще на пальцах объяснить.
Проходимся по ячейкам, или по массиву не важно, натыкаемся на слово "разделитель" запоминаем где оно, идем дальше и снова натыкаемся на слово "разделитель". Это и есть диапазон чисел которые необходимо умножить на 10. Затем снова идем в низ пока не натыкаемся на очередной разделитель. Так вот между первым и последним разделителем и есть диапазон первичных вычислений, а именно - надо найти разницу между теми числами которые были умножены на 10 и теми которые стоят за вторым по счету разделителем.

А как сделать запись в ячейку?
Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #10: 19 Декабрь 2017, 22:12 »

Нет, всё ещё как-то мутно... Первая группа у тебя 7 цен, вторая 5, третья 3... Кого домножать, кого не домножать, как вычитать - не ясно.
Попробуй сформулировать иначе, а? Ну, типа, "подобрать скины на сумму вот такую-то, но чтобы купить как можно больше" или как-нибудь похоже - без привязки к алгоритму, просто смысл задачи

Или .setDataArray - шлёпнуть весь сформированный массив значений в диапазон, или .setValue для одиночной ячейки
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
Sledo
Новичок
*
Offline Offline

Сообщений: 10


« Ответ #11: 19 Декабрь 2017, 22:21 »

Нет, всё ещё как-то мутно... Первая группа у тебя 7 цен, вторая 5, третья 3... Кого домножать, кого не домножать, как вычитать - не ясно.
Попробуй сформулировать иначе, а? Ну, типа, "подобрать скины на сумму вот такую-то, но чтобы купить как можно больше" или как-нибудь похоже - без привязки к алгоритму, просто смысл задачи

Или .setDataArray - шлёпнуть весь сформированный массив значений в диапазон, или .setValue для одиночной ячейки
В том то и проблема, что все именно так не однозначно, почему и приходится писать программу. Было бы просто я бы формул поналяпал и спал бы спокойно)
Ну вот первая группа, которая выходит на 7 цен, умножить каждую цену на 10 и затем каждую вычесть из каждой 5 цен следующей группы. Затем возьмется 5 цен, умножится на 10 и вычтится из каждой 3 цен. И так далее.
Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #12: 19 Декабрь 2017, 22:44 »

Все умноженные вычитаются? В смысле - вычесть сумму из каждой цены второй группы? Или каждую вычесть?


* Контра.png (14.04 Кб, 1118x150 - просмотрено 14 раз.)
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
Sledo
Новичок
*
Offline Offline

Сообщений: 10


« Ответ #13: 19 Декабрь 2017, 22:57 »

Все умноженные вычитаются? В смысле - вычесть сумму из каждой цены второй группы? Или каждую вычесть?
Вот файл для скачивания с формулами. Надо расширение вернуть на ods
https://drive.google.com/open?id=1fcRFjjTwzYIhpBc3QgleOLRj2c78fs3q
Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 504


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #14: 20 Декабрь 2017, 09:56 »

У тебя в 130-ой, 203-ей и 255-ой строках коэффициенты поехали.
Не заморачивайся с Гугл-диском, прикладывай файл прямо к сообщению - не такие и большие у тебя таблицы, эти 30 Кб форум выдержит

Ну, хорошо. Пусть это будет сформулировано так: если обменять десять комплектов нового скина на один старый, то доплата (выручка) составит столько-то...

Ладно. Допустим, для всей таблицы будут подсчитаны все эти разности. А что дальше? В "пошарпанном" коде дело заканчивалось сортировкой этого массива по убыванию. Имелось в виду, что нужно будет выбрать максимум? То есть весь полученный набор не нужен, нужно только одно число?
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
Страниц: 1 2 »   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!