Выбрать дату в календареВыбрать дату в календаре

Страницы: 1 2 След.
Увеличение и уменьшение значения ячейки с определенным шагом при нажатии "+" и "-" на клавиатуре
 
Спасибо большое, все работает)
Лень - двигатель прогресса, а энтузиазм его топливо
Увеличение и уменьшение значения ячейки с определенным шагом при нажатии "+" и "-" на клавиатуре
 
Добрый день!

Хочу настроить в таблице увеличение\уменьшение значения при нажатии клавиши "+"\"-" на клавиатуре для подбора нужного значения с определенным шагом. Данное действие должно быть доступно только для одного листа, а в идеале для определенного диапазона
Лень - двигатель прогресса, а энтузиазм его топливо
UDF в умных таблицах не пересчитываются автоматически, cо строкой Application.Volatile в коде пользовательской функции возникают ошибки
 
Потестирую пока вот такой вариант:
Код
Function ТекущаяДатаВремя(Optional ДиапазонОбновления As Range = Nothing)
    ТекущаяДатаВремя = Now
End Function
Лень - двигатель прогресса, а энтузиазм его топливо
UDF в умных таблицах не пересчитываются автоматически, cо строкой Application.Volatile в коде пользовательской функции возникают ошибки
 
Например:
Код
Option Explicit
Dim tabSTATE As Range
Dim esl_loess As Range
Dim psl_loess As Range

Function ПРОСАД(nEGE As String, opTYPE%, Optional MODE$ = "VOID", Optional sSetE$ = "VOID", Optional sSetSr$ = "VOID")
' (opTYPE: 0 - оба показателя; 1 - относительная просадочность; 2 - начальное просадочное давление)
  
  Dim dAvrE As Double, dAvrSr As Double 
  Dim soilINDEX As Integer

  Set tabSTATE = Worksheets("Відомість").Range("tb_State")
  Set esl_loess = Range("esl_loess")
  Set psl_loess = Range("psl_loess")

    With tabSTATE
      If sSetE = "VOID" Then dAvrE = AvrIF(.Columns(27), .Columns(1), nEGE, 0) Else dAvrE = CDbl(sSetE)
      If sSetSr = "VOID" Then dAvrSr = AvrIF(.Columns(28), .Columns(1), nEGE, 0) Else dAvrSr = CDbl(sSetSr)
      If MODE = "VOID" Then soilINDEX = AvrIF(.Columns(36), .Columns(1), nEGE, 0) Else soilINDEX = CInt(MODE)
      If dAvrE = 0 And dAvrSr = 0 Then ПРОСАД = "-": Exit Function
    End With

    If soilINDEX = 1 Then

      If opTYPE = 0 Then

        If Fxy(esl_loess, dAvrSr, dAvrE) >= 0.01 Then
          ПРОСАД = Round(Fxy(esl_loess, dAvrSr, dAvrE), 3) & " | " & Round(Fxy(psl_loess, dAvrSr, dAvrE), 2)
        Else
         ПРОСАД = "Н/П"
        End If

      ElseIf opTYPE = 1 Then

        If Fxy(esl_loess, dAvrSr, dAvrE) >= 0# Then
          ПРОСАД = Round(Fxy(esl_loess, dAvrSr, dAvrE), 3)
        Else
          ПРОСАД = "-"
        End If

      ElseIf opTYPE = 2 Then

        If Fxy(esl_loess, dAvrSr, dAvrE) >= 0.01 Then
          ПРОСАД = Round(Fxy(psl_loess, dAvrSr, dAvrE), 3)
        Else
          ПРОСАД = "-"
        End If

      End If

    ElseIf soilINDEX = 0 Then

      ПРОСАД = "-"

    End If

  'ПРОСАД = dAvrE & " | " & dAvrSr & " | " & soilINDEX
End Function
Вспомогательные функции для выше проведенной (находятся в отдельном модуле)
Код
Function Fxy#(Tablo As Range, r#, c#)

  Dim oneROW As Boolean, oneCOL As Boolean
  Dim xVAL#
  Dim ri&, ci&
  Dim x1#, x2#, y1#, y2#
  Dim a10#, a20#, a01#, a02#
  Dim a11#, a12#, a21#, a22#
    
  On Error Resume Next
    
    If Tablo.Rows.Count = 2 Then oneROW = True Else oneROW = False
    If Tablo.Columns.Count = 2 Then oneCOL = True Else oneCOL = False
    
    If oneROW = True And oneCOL = False Then
      ri = 2
      ci = 1 + FindIndex(Range(Tablo.Cells(1, 2), Tablo.Cells(1, Tablo.Columns.Count)), c)
        a01 = Tablo.Cells(1, ci):      a02 = Tablo.Cells(1, ci + 1)
        a11 = Tablo.Cells(ri, ci):     a12 = Tablo.Cells(ri, ci + 1)
          x1 = a01:       x2 = a02
          y1 = a11:       y2 = a12
          xVAL = c
    ElseIf oneROW = False And oneCOL = True Then
      ri = 1 + FindIndex(Range(Tablo.Cells(2, 1), Tablo.Cells(Tablo.Rows.Count, 1)), r)
      ci = 2
        a10 = Tablo.Cells(ri, 1):      a20 = Tablo.Cells(ri + 1, 1)
        a11 = Tablo.Cells(ri, ci)
        a21 = Tablo.Cells(ri + 1, ci)
          x1 = a10:       x2 = a20
          y1 = a11:       y2 = a21
          xVAL = r
    ElseIf oneROW = False And oneCOL = False Then
      ri = 1 + FindIndex(Range(Tablo.Cells(2, 1), Tablo.Cells(Tablo.Rows.Count, 1)), r)
      ci = 1 + FindIndex(Range(Tablo.Cells(1, 2), Tablo.Cells(1, Tablo.Columns.Count)), c)
        a01 = Tablo.Cells(1, ci):      a02 = Tablo.Cells(1, ci + 1)
        a10 = Tablo.Cells(ri, 1):      a20 = Tablo.Cells(ri + 1, 1)
        a11 = Tablo.Cells(ri, ci):     a12 = Tablo.Cells(ri, ci + 1)
        a21 = Tablo.Cells(ri + 1, ci): a22 = Tablo.Cells(ri + 1, ci + 1)
          x1 = a01:       x2 = a02
          y1 = Fx(r, a10, a20, a11, a21)
          y2 = Fx(r, a10, a20, a12, a22)
          xVAL = c
    ElseIf oneROW = True And oneCOL = True Then
      Fxy = 0: Exit Function
    End If
    
    Fxy = Fx(xVAL, x1, x2, y1, y2)
    
End Function

Function Fx(x#, x1#, x2#, y1#, y2#)
    Fx = y1 + (x - x1) * (y2 - y1) / (x2 - x1)
End Function

Function FindIndex&(rg As Range, V)
  Dim IncRg As Boolean, i&
  If rg.Cells(1) < rg.Cells(rg.Cells.Count) Then
    If V < rg.Cells(1) Then FindIndex = 1: Exit Function
    If V > rg.Cells(rg.Cells.Count) Then FindIndex = rg.Cells.Count - 1: Exit Function
    FindIndex = WorksheetFunction.Match(V, rg)
  Else
    If V > rg.Cells(1) Then FindIndex = 1: Exit Function
    If V < rg.Cells(rg.Cells.Count) Then FindIndex = rg.Cells.Count - 1: Exit Function
    FindIndex = WorksheetFunction.Match(V, rg, -1)
  End If
End Function

Function AvrIF(TargetRNG As Range, ConditionRNG As Range, Condition As String, Optional altVAL As String)
  On Error GoTo valERR
    AvrIF = Application.WorksheetFunction.AverageIfs(TargetRNG, ConditionRNG, Condition)
Exit Function
valERR: AvrIF = altVAL
End Function
Изменено: lodman_geo - 09.12.2019 12:41:18
Лень - двигатель прогресса, а энтузиазм его топливо
UDF в умных таблицах не пересчитываются автоматически, cо строкой Application.Volatile в коде пользовательской функции возникают ошибки
 
Дмитрий(The_Prist) Щербаков, Вам сбросить файл, или же пример кода? Просто в файле у меня куча модулей, сложно будет разобраться
Изменено: lodman_geo - 09.12.2019 12:28:16 (опечатка)
Лень - двигатель прогресса, а энтузиазм его топливо
UDF в умных таблицах не пересчитываются автоматически, cо строкой Application.Volatile в коде пользовательской функции возникают ошибки
 
Цитата
Дмитрий(The_Prist) Щербаков написал:
Вероятно, они просто не учитывают использование их в умной таблиц
А как это можно учесть, можно пример, пожалуйста?  
Лень - двигатель прогресса, а энтузиазм его топливо
UDF в умных таблицах не пересчитываются автоматически, cо строкой Application.Volatile в коде пользовательской функции возникают ошибки
 
Добрый день!

Краткое описание проблемы: Наткнулся на проблему, есть книга Execel с набором макросов и пользовательских функций, функции сложные и используют дополнительные функции. Проблема состояла в том, что пользовательские функции, вбитые в "умную таблицу" "отказывались" пересчитываться автоматически, пересчитывались только через двойной клик и Enter.  Частично проблему решила строка Application.Volatile, однако при открытии новой книги Excel или же копировании и вставке все пользовательские функции сваливаются в ошибку, а при копировании и вставке только значений, вставляется текст ошибки

Вопрос: можно ли обойтись без Application.Volatile? Если у кого-то была подобная проблема, как вы с ней боролись?)
 
Лень - двигатель прогресса, а энтузиазм его топливо
Цикл вычислений по не смежному диапазону ячеек
 
Цитата
Пытливый написал:
Добрый день. Покажите в файле примере - что вам нужно - какие ячейки каких столбцов каких строк нужно проходить и что при прохождении с ними делать?А то в текстовом режиме очень неудобно помогать.
Пишу макрос, который на основе уже имеющихся данных заполнял бы пустые ячейки по рангу (проверил на столбце Физ.свойства[5] вроде как работает нормально)
Что делает макрос: ищет максимальное и минимальное значение в нужном диапазоне (в примере: Физ.свойства[5]), а за тем заполняет пустые ячейки в это же диапазоне случайными значениями от минимального до максимального
Что необходимо: заполнить столбцы 5 - 14; 16 - 17; 19; 20; 18 (в данном порядке)
при том: столбец 20 вычисляется как 19 - 21, а столбец 18 = (22 * 21) + 20
Код
Sub VALcolect_()
Dim EGE As Range, ValList As Range, ExpVal As Range
Dim valARR, FvalARR, i As Long, j&, k&, q&
Set ExpVal = Range("gen[ИГЕ]")
Set ValList = Range("Физ.свойства[18]")
Set EGE = Range("Физ.свойства[0]")
'1.Формуруем набор рангов объекта_______________________________________
Dim vItem, avArr, li As Long
ReDim avArr(1 To Rows.Count, 1 To 1)
With New Collection
On Error Resume Next
 For Each vItem In EGE.Value
 .Add vItem, CStr(vItem)
 If ERR = 0 Then
  li = li + 1: avArr(li, 1) = vItem
  Else: ERR.Clear
 End If
 Next
End With
    If li Then ExpVal.Resize(li).Value = avArr
'2. Поиск минимального и максимального значения для каждого ранга_______
Erase valARR: Erase FvalARR
ReDim valARR(1 To Rows.Count): ReDim FvalARR(1 To Rows.Count)
On Error Resume Next
For j = 1 To ExpVal.Count
minD = 9999
maxD = -9999
 For i = 1 To EGE.Count
 If EGE.Cells(i, 1) = avArr(j, 1) Then valARR(i) = ValList.Cells(i)
 If valARR(i) <> "" And valARR(i) <> "-" Then
 k = k + 1: FvalARR(k) = valARR(i)
 If minD > FvalARR(k) Then minD = FvalARR(k)
 If maxD < FvalARR(k) Then maxD = FvalARR(k)
 End If: Next i
If minD = 9999 Then GoTo nXt
If maxD = -9999 Then GoTo nXt
'3. Заполнение пустых ячеек по рангу____________________________________
For q = 1 To EGE.Count
If EGE.Cells(q, 1) = avArr(j, 1) Then
 If IsEmpty(ValList.Cells(q, 1)) Then
 ValList.Cells(q, 1).Value = _
 Application.RandBetween(minD * 1000, maxD * 1000) / 1000
End If: End If
Next q
Erase valARR: Erase FvalARR
ReDim valARR(1 To Rows.Count): ReDim FvalARR(1 To Rows.Count)
nXt: Next j
End Sub

Изменено: lodman_geo - 20.06.2019 11:41:41 (Исправлены нелогичные моменты кода)
Лень - двигатель прогресса, а энтузиазм его топливо
Цикл вычислений по не смежному диапазону ячеек
 
Sanja, Спасибо примерно это я и искал)
Лень - двигатель прогресса, а энтузиазм его топливо
Цикл вычислений по не смежному диапазону ячеек
 
Цитата
Sanja написал:
Макросом
Все гениальное просто, согласен)
А не подскажете как правильно задать этот диапазон или лучше задать циклы по этим столбцам отдельно, просто думал, может есть способ поизящнее)
P.S. как отдельно сделать я знаю :)  
Изменено: lodman_geo - 20.06.2019 09:41:49
Лень - двигатель прогресса, а энтузиазм его топливо
Цикл вычислений по не смежному диапазону ячеек
 
Добрый день!
Возник такой вопрос, необходимо пройтись циклом вычислений по не смежному диапазону, например: по столбцам и в следующем порядке: Y - X - A - B - C - D - E - T - U - X
Как это можно реализовать?  
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
IKor,спасибо за пример, но мой нышешний шаблон как раз в массивах расписан, просто возникла необходимость написать подобный алгорифм, только в виде VBA кода (уперся в предел возможностей формул)
Возникла необходимость создания макроса для наполнения таблицы данными на основе уже имеющихся данных в ней (забивать в ручную 10 тысяч значений очень муторно), сложность в том, что данные X и множества Yi должны коррелироваться, плюс ко всему таблица ранжирована на классы
Простенький кустарный макрос я себе сделал (через формулы массива и вспомогательной таблицы) однако просчёты идут очень долго, возникла необходимость перейти к массивам. Плюс ко всему, раз уже лезу в массивы, хотелось бы повысить точность выводимых данных
Цитата
IKor написал:
смущают несколько показаний Y для одного ранга и одного показания X - какое значение следует использовать?
Используются все, через аппроксимацию и корреляцию. Хорошо в этом плане показала себя полиноминальная функция  
Изменено: lodman_geo - 22.05.2019 18:24:06
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
Цитата
Ігор Гончаренко написал:
WorksheetFunction.Forecast_Linear(2, Yarr, Xarr)
Можно пример, не могу никак применить
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
Ігор Гончаренко, Как-то так получилось
Код
Function ValByRank(RankList As Range, ValList As Range, RankVal As Range)
Dim valARR, i As Long
Dim FvalARR, j&, k&
ReDim valARR(1 To Rows.Count, 1 To 1)
On Error Resume Next
  For i = 1 To RankList.Count
    If RankList.Cells(i, 1) = RankVal Then
      valARR(i, 1) = ValList.Cells(i, 1)
    End If
  Next i
ReDim FvalARR(1 To UBound(valARR), 1 To 1)
  For j = 1 To UBound(valARR)
    If valARR(j, 1) <> "" Then
      k = k + 1
        FvalARR(k, 1) = valARR(j, 1)
    End If
  Next j
    ValByRank = FvalARR
End Function
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
Цитата
Ігор Гончаренко написал:
слова набрать подразумевает из всего, что там есть нужно НАБРАТЬ то, что подходит для расчетовможно придумать 1000 и 1 способ как это сделатьПОнял
Понял ошибку)
Как бы мне таблицу с данными отсортировать по критерию (РАНГУ) и добавить в массив или создать отдельные массивы для каждого ранга (ранги, так как и значения могут меняться)
Мне только приходит в голову поиск уникальных значений
Изменено: lodman_geo - 20.05.2019 16:54:09
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
Ігор Гончаренко, А как бы мне набрать массивы по условию (в моем случае РАНГу), если у меня есть пустые ячейки и "-"?)
Изменено: lodman_geo - 20.05.2019 16:41:17
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
Ігор Гончаренко,Спасибо!
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
Ігор Гончаренко, А есть VBA аналог, что бы можно было вставить в существующую функцию?
Важное условие, что бы таблица осталась в исходном виде
Лень - двигатель прогресса, а энтузиазм его топливо
Перенос таблиц c данными из EXCEL в шаблон WORD
 
Цитата
Андрей Лящук написал:
создаете таблицу типа
Я так понимаю "умную таблицу" создать нужно?
И как сделать данный путь динамическим? Что бы не только я мог это делать
Изменено: lodman_geo - 20.05.2019 15:10:41
Лень - двигатель прогресса, а энтузиазм его топливо
Расчёт значения Y зависимого от значения X по ранжированой таблице данных при помощи полиноминальной функции
 
Добрый день!
Задача: есть два зависимых стобца данных X и Y, которые разделены на классы: столбец РАНГ. Необходимо найти значение Y по X в зависимости от РАНГа при помощи полиноминальной функции
Таблица имеет следующий вид (см. Пример):
1. Столбец РАНГ: целые значения как просто с цифрами так и цифры с буквенными индексами: 1; 2; 3а; 3б и тд
2. Столбец X: целые и десятичные числа
3. Столбец Y: числа от 0 до 1, а так же пустые ячейки и знаки "-" (когда значение не верное или является статошибкой)
4. Таблица данных должна остаться в исходном виде
Простенький VBA расчёта по полиноминальной функции я себе написал, но он не идеален:
1. Не работает в диапазонах значений
2. Не работает при наличии пустых ячеек или значений "-" в ячейках
3. Ну и самое главное он (как и я) не знает как расчитывать полиномы по рангам)
Код
Function ПОЛИНОМ_ЗНАЧ(WorkRange As Range, CondRange As Range, CondVAL As Double)
  With Application
    LinEstVAL = .LinEst(WorkRange, .Power(CondRange, Array(1, 2, 3, 4, 5, 6)))
      a_1 = .Index(LinEstVAL, 1) * CondVAL ^ 6
      a_2 = .Index(LinEstVAL, 1, 2) * CondVAL ^ 5
      a_3 = .Index(LinEstVAL, 1, 3) * CondVAL ^ 4
      a_4 = .Index(LinEstVAL, 1, 4) * CondVAL ^ 3
      a_5 = .Index(LinEstVAL, 1, 5) * CondVAL ^ 2
      a_6 = .Index(LinEstVAL, 1, 6) * CondVAL ^ 1
      a_7 = .Index(LinEstVAL, 1, 7)
  End With
ПОЛИНОМ_ЗНАЧ = a_1 + a_2 + a_3 + a_4 + a_5 + a_6 + a_7
End Function
Изменено: lodman_geo - 20.05.2019 16:02:09
Лень - двигатель прогресса, а энтузиазм его топливо
Перенос таблиц c данными из EXCEL в шаблон WORD
 
Цитата
Ігор Гончаренко написал:
когда устанете от попыток решить эту задачу - обращайтесь
Если конечно не сложно, буду очень благодарен)
Пример нужен?)
Изменено: lodman_geo - 20.05.2019 14:49:29
Лень - двигатель прогресса, а энтузиазм его топливо
Перенос таблиц c данными из EXCEL в шаблон WORD
 
Добрый день!
Делаю шаблон автоматической обработки больших массивов данных и столкнулся с проблемой: "Как в автоматическом режиме вставить таблицы с данными в шаблон отчета WORD"
Что нужно перенести:
1. Сводную таблицу (1 - 3 листа А3 альбомной ориентации)
2. Таблица с набором данных (от 1 до n страниц А3 альбомной ориентации, разбита по категориям - от 1 до k)
3. Таблицы статистики,  которые формируются на основе таблицы 2 по категориям (от 1 до k таблицы с графиками на 2 листа А4)

Куда нужно перенести:
Шаблон WORD с заранее подготовленными маркерными метками или закладками

Сложность: Значений в таблице 2 может быть до 10-ка тысяч

P.S. Я понимаю, что подобного рода задачка так просто не решается, мне бы хотя бы примерное решение либо примерное направление в котором нужно двигаться
Изменено: lodman_geo - 20.05.2019 13:48:50
Лень - двигатель прогресса, а энтузиазм его топливо
Перевод таблицы с двумя переменными (кросс-таблицы) в двумерный массив VBA, для дальнейшего экспорта функции поиска значений по данной таблицы
 
Добрый день!

Задача: Перенести значение из исходной таблицы, по которой функцией VBA выполняется интерполяция по двум переменным, в двухмерный массив
Вопрос: Как это правильнее сделать и придется ли при этом менять код?
Поиск значений происходит при помощи следующего макроса (автор: Ігор Гончаренко ) код
Код
Function Fxy#(Tablo As Range, r#, c#)
  Dim ri&, ci&
  ri = 1 + FindIndex(Range(Tablo.Cells(2, 1), Tablo.Cells(Tablo.Rows.Count, 1)), r)
  ci = 1 + FindIndex(Range(Tablo.Cells(1, 2), Tablo.Cells(1, Tablo.Columns.Count)), c)
  Fxy = Fx(c, Tablo.Cells(1, ci), Tablo.Cells(1, ci + 1), _
  Fx(r, Tablo.Cells(ri, 1), Tablo.Cells(ri + 1, 1), Tablo.Cells(ri, ci), Tablo.Cells(ri + 1, ci)), _
  Fx(r, Tablo.Cells(ri, 1), Tablo.Cells(ri + 1, 1), Tablo.Cells(ri, ci + 1), Tablo.Cells(ri + 1, ci + 1)))
End Function
 
 
Function Fx(x#, x1#, x2#, y1#, y2#)
  Fx = y1 + (x - x1) * (y2 - y1) / (x2 - x1)
End Function
 
 
Private Function FindIndex&(rg As Range, V)
  Dim IncRg As Boolean, i&
  If rg.Cells(1) < rg.Cells(rg.Cells.Count) Then
    If V < rg.Cells(1) Then FindIndex = 1: Exit Function
    If V > rg.Cells(rg.Cells.Count) Then FindIndex = rg.Cells.Count - 1: Exit Function
    FindIndex = WorksheetFunction.Match(V, rg)
  Else
    If V > rg.Cells(1) Then FindIndex = 1: Exit Function
    If V < rg.Cells(rg.Cells.Count) Then FindIndex = rg.Cells.Count - 1: Exit Function
    FindIndex = WorksheetFunction.Match(V, rg, -1)
  End If End Function
Изменено: lodman_geo - 13.05.2019 17:30:01
Лень - двигатель прогресса, а энтузиазм его топливо
Поиск значения в кросс-таблице с заданным шагом в полях
 
Цитата
Ігор Гончаренко написал:
в строках 1..8 кода текст функции Fxy

Увидел) Спасибо Вам большое)
Внешние скобочки не рассмотрел)
Изменено: lodman_geo - 10.05.2019 14:09:47
Лень - двигатель прогресса, а энтузиазм его топливо
Поиск значения в кросс-таблице с заданным шагом в полях
 
Ігор Гончаренко, Простите за нескромный вопрос, а как рассчитывается Fxy? (это  я для себя, больное любопытство)
Просто я не вижу ни формулы, ни функции и у меня дисонанс внутренний  :)  
Изменено: lodman_geo - 10.05.2019 13:59:32
Лень - двигатель прогресса, а энтузиазм его топливо
Поиск значения в кросс-таблице с заданным шагом в полях
 
Jack Famous, Вот эта часть кода почему-то не работает (как я думаю), когда даже вручную присваиваю OneCol и OneRow значение "True", появляется ошибка ЗНАЧ
Код
'===== СТРОКИ
rStep = --Format$(arrTbl(3, 1) - arrTbl(2, 1), "0.0000"): If valRow < arrTbl(2, 1) Or valRow > arrTbl(UBound(arrTbl, 1), 1) Then GoTo ex
rMin = PRV_RoundAccSokol(valRow, rStep): If rMin + rStep > arrTbl(UBound(arrTbl, 1), 1) Then OneRow = True

'===== СТОЛБЦЫ
cStep = --Format$(arrTbl(1, 3) - arrTbl(1, 2), "0.0000"): If valCol < arrTbl(1, 2) Or valCol > arrTbl(1, UBound(arrTbl, 2)) Then GoTo ex
cMin = PRV_RoundAccSokol(valCol, cStep): If cMin + cStep > arrTbl(1, UBound(arrTbl, 2)) Then OneCol = True
 
'===== 4 значения
iCol = PRV_MatchByStep(cMin, arrTbl(1, 2), cStep) + 1: iRow = PRV_MatchByStep(rMin, arrTbl(2, 1), rStep) + 1: ReDim arrX(0 To 3): arrX(0) = arrTbl(iRow, iCol)
    If OneRow Then
        If OneCol Then ReDim Preserve arrX(0 To 0) Else ReDim Preserve arrX(0 To 1): arrX(1) = arrTbl(iRow, iCol + 1)
    Else
        arrX(1) = arrTbl(iRow + 1, iCol): If OneCol Then ReDim Preserve arrX(0 To 1) Else arrX(2) = arrTbl(iRow, iCol + 1): arrX(3) = arrTbl(iRow + 1, iCol + 1)
    End If
Изменено: lodman_geo - 10.05.2019 12:05:39
Лень - двигатель прогресса, а энтузиазм его топливо
Поиск значения в кросс-таблице с заданным шагом в полях
 
Jack Famous, Вы просили Вам больше примеров сделать, я пытался, но понял, что мне проще написать самому. Посмотрите, пожалуйста, очень интересно ваше мнение :)
1. Добавил фильтр значений, когда критерий совпадает со строкой\столбцом таблицы (строка 27 - 30)
2. Добавил расчётную формулу для биполярной интерполяции
3. Вернул замену пустых ячеек на "0" из тестовой версии кода автора Jack Famous
Код
Option Explicit
'====================================================================================================
Function FILE_GetValuesFromCrossTable(rngTbl As Range, valRow#, valCol#) As String
Dim arrTbl, iRow&, iCol&
Dim cStep#, cMin#, OneCol As Boolean
Dim rStep#, rMin#, OneRow As Boolean
Dim x, arrX()
Dim i, j
If rngTbl Is Nothing Or valRow = 0 Or valCol = 0 Then Exit Function
If rngTbl.Rows.Count < 3 Or rngTbl.Columns.Count < 3 Then Exit Function Else arrTbl = rngTbl.Value2
 
'===== СТРОКИ
rStep = --Format$(arrTbl(3, 1) - arrTbl(2, 1), "0.0000"): If valRow < arrTbl(2, 1) Or valRow > arrTbl(UBound(arrTbl, 1), 1) Then GoTo ex
rMin = PRV_RoundAccSokol(valRow, rStep): If rMin + rStep > arrTbl(UBound(arrTbl, 1), 1) Then OneRow = True
 
'===== СТОЛБЦЫ
cStep = --Format$(arrTbl(1, 3) - arrTbl(1, 2), "0.0000"): If valCol < arrTbl(1, 2) Or valCol > arrTbl(1, UBound(arrTbl, 2)) Then GoTo ex
cMin = PRV_RoundAccSokol(valCol, cStep): If cMin + cStep > arrTbl(1, UBound(arrTbl, 2)) Then OneCol = True
 
'===== 4 значения
iCol = PRV_MatchByStep(cMin, arrTbl(1, 2), cStep) + 1: iRow = PRV_MatchByStep(rMin, arrTbl(2, 1), rStep) + 1: ReDim arrX(0 To 3): arrX(0) = arrTbl(iRow, iCol)
    If OneRow Then
        If OneCol Then ReDim Preserve arrX(0 To 0) Else ReDim Preserve arrX(0 To 1): arrX(1) = arrTbl(iRow, iCol + 1)
    Else
        arrX(1) = arrTbl(iRow + 1, iCol): If OneCol Then ReDim Preserve arrX(0 To 1) Else arrX(2) = arrTbl(iRow, iCol + 1): arrX(3) = arrTbl(iRow + 1, iCol + 1)
    End If
'===== Фильтрация arrX при valRow и valCol кратным Step (добавлено)
If valRow = rMin Or valCol = cMin Then arrX(3) = 0 Else
If valRow = rMin Then arrX(1) = 0 Else
If valCol = cMin Then arrX(2) = 0
'FILE_GetValuesFromCrossTable = iRow & " | " & iCol
iRow = -1
    For Each x In arrX
        'If Len(x) Then iRow = iRow + 1: arrX(iRow) = x                                         'пустые ячейки приводят к ошибке
        iRow = iRow + 1: If Len(x) Then arrX(iRow) = x Else arrX(iRow) = 0                      '(скопировано) заменяем в цикле пустые значения на нули
    Next x
If iRow = -1 Then Exit Function Else ReDim Preserve arrX(0 To iRow):
    On Error GoTo ex
    i = arrX(0) + ((arrX(2) - arrX(0)) / cStep) * (valCol - cMin)                               '(добавлено) интерполяция по valCol для iRow
    j = arrX(1) + ((arrX(3) - arrX(1)) / cStep) * (valCol - cMin)                               '(добавлено) интерполяция по valCol для iRow + 1
FILE_GetValuesFromCrossTable = i + ((j - i) / rStep) * (valRow - rMin)                          '(добавлено) интерполяция по valRow
'FILE_GetValuesFromCrossTable = Application.Round(i + ((j - i) / rStep) * (valRow - rMin), 0)   '[опционально] округление до целого числа
'FILE_GetValuesFromCrossTable = FILE_GetValuesFromCrossTable & vbLf & Join(arrX, " - ")
ex: End Function
'====================================================================================================
Private Function PRV_RoundAccSokol(valNum#, Accuracy#) As Double
If (1000000 * valNum) Mod (1000000 * Accuracy) = 0 Then PRV_RoundAccSokol = valNum Else PRV_RoundAccSokol = Int(valNum / Accuracy) * Accuracy
End Function
'====================================================================================================
Private Function PRV_MatchByStep(valFind#, ByVal valFirst#, Step#) As Long
PRV_MatchByStep = ((valFind - valFirst) / Step) + 1
End Function
'====================================================================================================
Изменено: lodman_geo - 09.05.2019 02:45:32
Лень - двигатель прогресса, а энтузиазм его топливо
Поиск значения в кросс-таблице с заданным шагом в полях
 
Цитата
Jack Famous написал:
создайте новый файл, сохраните его, как двоичную книгу (.xlsb) и попробуйте перетянуть мой модуль из тестового файла в этот новый
В новом файле все работает отлично, ведать мой шаблон запартачен :sceptic:
Лень - двигатель прогресса, а энтузиазм его топливо
Поиск значения в кросс-таблице с заданным шагом в полях
 
Цитата
Jack Famous написал:
попробуйте перетянуть мышкой модуль Tester из файла-примера в свой, а то, что копировали в свои модули от меня удалите
То же самое(
Лень - двигатель прогресса, а энтузиазм его топливо
Поиск значения в кросс-таблице с заданным шагом в полях
 
Jack Famous, Снова ошибка
https://drive.google.com/open?id=1wQYk3mEWpg6oATZ0rO32FiFL8rhc9Yph
У меня Excel 2010 если это поможет  
Изменено: lodman_geo - 08.05.2019 16:08:00
Лень - двигатель прогресса, а энтузиазм его топливо
Страницы: 1 2 След.
Наверх