Как стать автором
Обновить
2
0

Пользователь

Отправить сообщение

У меня такие касио. Идут с 2009 на одной батарейке

Яка прикра новина!

А не воевать совсем не вариант?

Как будем LEFT JOIN форматировать?

Подозреваю, что никак

Возможно я не совсем понимаю понятие "консоль". У меня в FAR и cmd переключает

Пример ниже

Вот пример моего скрипта:

; Переключение языков по Shift, с сохранением раскладки для языка
; Левый - Английский
; Правый - Украинский, текущая клавиатура (на язык повешено 2 раскладки)
#NoEnv
#SingleInstance force

Process Priority,, High

layouts := GetLayoutList()

~LShift Up::
  if (A_PriorKey = "LShift") 
    SwtichLang(layouts, 1033) ; English
return

~RShift Up::
  if (A_PriorKey = "RShift") 
    SwtichLang(layouts, 1058) ; Ukraine
return

;~LShift Up::
;  if (A_PriorKey = "LShift") 
;    SwtichLang(layouts, 0)
;return

SwtichLang(ByRef layouts, LangId) {
  InputLocaleID := GetKeyboardLayout()
  lang := InputLocaleID & 0x0000FFFF 

  if (LangId == 0) {
    prev := 0
    for index, element in layouts {
      if (index == lang && prev != 0) {
        SwtichLang(layouts, prev)
        return
      } else 
        prev := index
    }
    if (prev != 0) {
      SwtichLang(layouts, prev)
      return
    }
  } else
  if (lang != LangId) {
    layouts[lang] := InputLocaleID  ; Сохраняем раскладку текущего языка
    newLocale := layouts[LangId]

    kbd_msg(Format("{:U}", GetLangName(LangId)))
;    Send, {Ctrl Down}{Shift Down}{Shift Up}{Ctrl Up}
    ControlGetFocus, ctl
    PostMessage 0x50, 3, %newLocale%, %ctl%, A
  }
}

GetKeyboardLayout() {
   hWnd := WinExist("A")

   WinGetClass, winClass
   if ((winClass != "ConsoleWindowClass") || (b := SubStr(A_OSVersion, 1, 2) = "10"))  {
      if b {
         dhw_prev := A_DetectHiddenWindows
         DetectHiddenWindows, On
         hWnd := WinExist("ahk_exe conhost.exe")
         DetectHiddenWindows, % dhw_prev
      }
      threadId := DllCall("GetWindowThreadProcessId", Ptr, hWnd, UInt, 0)
      lyt := DllCall("GetKeyboardLayout", Ptr, threadId, UInt)
      return lyt
   }
   else {
      WinGet, consolePID, PID
      DllCall("AttachConsole", Ptr, consolePID)
      VarSetCapacity(lyt, 16)
      DllCall("GetConsoleKeyboardLayoutName", Str, lyt)
      DllCall("FreeConsole")
      return lyt
   }
}

GetLayoutList() {
    aLayouts := []
    size := DllCall("GetKeyboardLayoutList", "UInt", 0, "Ptr", 0)
    VarSetCapacity(list, A_PtrSize*size)
    size := DllCall("GetKeyboardLayoutList", Int, size, Str, list)
    Loop % size { ; для каждого языка сохраняем одну раскладку
        aLayout := NumGet(list, A_PtrSize*(A_Index - 1))
        lang := aLayout & 0x0000FFFF
        if (aLayouts[lang] == null) 
          aLayouts[lang] := aLayout 
    }
    Return aLayouts
}

GetLangName(LocID, FullName = false) {
  static SISO639LANGNAME            := 0x0059 ; ISO abbreviated language name, eg "EN"
  static LOCALE_SENGLANGUAGE        := 0x1001 ; Full language name, eg "English"

  LCType := FullName ? LOCALE_SENGLANGUAGE : SISO639LANGNAME
  Size := (DllCall("GetLocaleInfo", UInt, LocID, UInt, LCType, UInt, 0, UInt, 0) * 2)
  VarSetCapacity(localeSig, Size, 0)
  DllCall("GetLocaleInfo", UInt, LocID, UInt, LCType, Str, localeSig, UInt, Size)
  Return localeSig
}

kbd_msg(text) {
  no_detect_window := -1
  ToolTip, %text%, A_CaretX + 10, A_CaretY - 20
  SetTimer, KbdRemoveToolTip, -1000
  return
    
  KbdRemoveToolTip:
  ToolTip
  no_detect_window := 1
  return
}

Ппоблема трех раскладок решается двумя языками ввода, и для одного из них две раскладки клавиатуры. Язык ввода переключается ctrl-shift, а раскладка в пределах языка alt-shift. En, Ru, Ua. Английский (En)и украинский языки (две раскладки Ukr Ua и Ukr Ru).

Я настроил себе переключение тоже через AutoHotKey. Но я поборол проблемы с консолью.

Язык ввода меняю через длинное нажатие на LShift / RShift, предыдущую раскладку сохраняю.

Первая задача сводится наличию не менее трех пар карт "квадратов"

А зачем боятся джойна? Хранение в справочнике операций счет, главный в группировке решает все проблемы

При такой структуре есть необходимость ускорять расчеты на начало периода. Т.к. весь учет происходит от начала истории. Есть разные способы. Я для себя изобрел следующий:

В таблицу OPER добавляется поле "ПРИЗНАК ОСТАТКА" у меня OST, для обычной проводки в этом поле 0.
Периодически (раз в день/неделю/месяц/квартал/год) происходит закрытие периода и в таблицу OPER добавляются текущие остатки по счетам/организациям. Но не виде проводки, а одиночные строки с полем OST = 1. И в отдельную таблицу вносится дата закрытия (у меня PERIOD)
В дальнейшем для получения отчетов с остатками на начало по таблице PERIOD находим ближайшую дату снизу к дате начала периода.
И отчет модернизируется до
where (o.ost = 1 and o.date_oper = 'дата закрытия') or (o.ost = 0 and o.date_oper between 'дата закрытия' + 1 and 'конечная дата отчета')

Такая схема работает у меня очень давно и проблем с производительностью нет никаких

Еще раз про структуру таблицы "полупроводок" пусть будет OPER

  1. Дата

  2. ID счета

  3. ID контрагента (склад/сотруник/покупатель/поставщик и т.д.)

  4. Знак (1 для дебета, -1 для кредита)

  5. Сумма

  6. ID книги (в какой должна фигурировать проводка)

  7. Пара (поле связывающее строку дебет со строкой кредит, в моем случае это поле одинаковое для двух строк)


    Далее необязательные поля, но важные

  8. ID документа (у одного документа есть набор проводок)

  9. Примечание (описание проводки)

У меня еще есть дополнительные поля, но для объяснения они пока не важны


Получение одной проводки из такой таблицы получается при помощи join
select d.*, k.* from oper d
join oper k on k.para = d.para and k.sign = -1
where d.sign = 1

В таблицу проводок добавляется поле LedgerID и главная книга это простой отчет
с остатком на начало, оборотами и остатком на конец

select LedgerID, AccountId,
sum(case when sign = 1 and date_oper < '01.01.2021' then summa else 0 end) debet_begin,
sum(case when sign = -1 and date_oper < '01.01.2021 then summa else 0 end) kredit_begin,
sum(case date_oper < '01.01.2021 then sign * summa else 0 end) summa_begin,
sum(case when sign = 1 and date_oper >= '01.01.2021' then summa else 0 end) debet_turnout,
sum(case when sign = -1 and date_oper >= '01.01.2021' then summa else 0 end) kredit_turnout,
sum(case date_oper >= '01.01.2021' then sign * summa else 0 end) sum_turnout,
sum(case when sign = 1 then summa else 0 end) debet_end,
sum(case when sign = -1 then summa else 0 end) kredit_end, sum(sign * summa) summa_end
from oper
where date_oper <= '31.01.2021'
group by LedgerID, AccountId

Все же "книга" это свойство "проводки". Наравне со счетом, организацией, суммой.

Для ускорения можно сначала сгруппировать, а потом уже на готовые данные делать join.

Обычно такой запрос тоже делается не по всем счетам, а только по какой-то группе. Для этого я объединяю с таблицей групп счетов.

Структура такой таблицы простая (id_группы, id_счета)

Да, конечно есть.

select o.CustId, o.AccountId, min(c.adress), sum(o.summa * o.sign) from oper o

left join customers c on c.id = o.CustId

group by o.CustId, o.AccountId

Итоги считаются по паре CustID, AccountId. А дальнейшие подитоги это не дело СУБД, легко решается на уровне генератора отчетов.
Но можно и извратиться для получения этих данных одним запросом.
но тут надо включать тяжелую артиллерию SQL - "WITH RECURSIVE"

Я не совсем понимаю вопрос.

Вам непонятно как сделать сумму по "дереву" счетов?
В древовидном справочнике счетов есть поле "Родитель".
Можно добавить еще одно "Родитель для группировки". Здесь и будет самьій верхний уровень. Зачем добавлять это поле в проводку я не понимаю.

select СЧЕТ.ГЛАВНЫЙ_СЧЕТ,
sum(case when ПРОВОДКИ.ЗНАК = 1, ПРОВОДКИ.СУММА else 0 end) debit_turnout,
sum(case when ПРОВОДКИ.ЗНАК = -1, ПРОВОДКИ.СУММА else 0 end) credit_turnout,
from ПРОВОДКИ
join СЧЕТ on СЧЕТ.id = ПРОВОДКИ.счета
group by СЧЕТ.ГЛАВНЫЙ_СЧЕТ

У меня на этот случай нет никаких ограничений на уровне СУБД. Пользователь сам решает какой счет использовать и с каким уровнем вложенности работать.
Для запрета на уровне СУБД в справочнике счетов достаточно ввести поле (самый низкий уровень), и разрешать использовать только такие поля. Поле обновлять автоматически при редактировании справочника счетов.

Информация

В рейтинге
Не участвует
Откуда
Украина
Зарегистрирован
Активность