Архив рубрики: Про программирование

Исправляем косяки в битриксе

Очередной день с программированием.

Как вы помните, я познакомился с каналом Михаила Базарова на ютубе, и проникся его приверженностью документации битрикса. Недолго думая, я решил преобразовывать сайт магазина подарков своими силами — это было ошибкой.

Сначала создал папку local, куда скопировал шаблоны сайта, а активный шаблон не был первым, и я недоумевал, почему дизайн сайта слетел. Оказывается, все, что в папке local — имеет преимущество над другими папками, а значит, пока мой главный шаблон не скопируется, дизайна не будет.

Мое внутреннее негодование усилилось, когда я начал проверять восстановление дизайна. Часть кнопок пропала, отвалились виджеты, корзина стала незаметной на общем фоне.

Я начал копаться в сайте и файлах, и понял, что часть скриптов и изображений прописаны абсолютными путями к старому шаблону. Раз уж взялся, надо доделывать.

Первая попытка — найти ссылающиеся файлы прямым перебором увенчалась провалом. Файлов много, понять логику без опта невозможно.

Вторая попытка озарила меня только что — открыть сайт в режиме кода и смотреть, что к чему обращается. Так я нашел скрипты, вызывающие другие скрипты, и поменял пути. Сразу восстановились виджеты соц.сетей и картинки в карточке товара.

Далее оставался один скрипт черной пятницы, который оказался функцией INCLUDE в шаблоне. Если бы я не занимался php в прошлый раз, не догадался бы. Нашел этот включаемый файл, изменил в нем пути, и теперь ошибок не осталось.

Последнее действие — сбросить кеш сайта и пройтись по нему в поисках проблем. И нашел — оказалось, я сохранял действия в UTF-8, а сайт работает в CP-1251. Пришлось не просто найти все измененные файлы и пересохранить файлы, но и переписать все тексты заново.

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

PHP-шпаргалка

Конструкция открывается и закрывается:

<?php Здесь пишется код ?>

Вид переменных:

$a, или $blababla, или $supermegaparamname

Особый гемор:

  • всегда ставить точку с запятой «;» в конце строки
  • стараться избегать пробелов в конце строк, это ведет к ошибкам

Присвоение значений переменным:

$a = 10;

$a = «Аз есьм значение переменной»;

Операции с переменными самые обычные:

$a = $a+1; увеличивает на 1 значение

$a++; увеличивает на 1 значение

$a—; тут два минуса, уменьшает на 1 значение

$a = $b * $c; перемножение

Вывод значений:

echo «Да будет переменная $a»; для строки единичных значений

print $a; — для массивов чаще

Массив создается повторением переменной с разными значениями:

$param = «Иван»;

$param = «Иванович»;

$param = 21;

$param = «мужчина»;

Встроенные функции:

count($param); — посчитает количество ячеек в массиве

isset($param); — проверит, есть ли такая переменная

empty($param); — проверит, пустая я ли переменная

date(«y-m-d»); — выводит текущую дату. Можно играть кеглем и разделителем

date(«h-i-s»); — выводит текущее время. Можно играть разделителем.

Работа с функциями php

Объявляем функцию с именем hello и переменной $name. Функция введет имя во фразу, а выведется при обращении к имени функции с назначением значения в функцию.

function hello($name){

echo «$name, привет!»

}

hello(«Степан»);

Тоже самое с двумя переменными:

function hello($name, $sur_name){

echo «$name $sur_name, привет!»

}

hello(«Степан», «Чельцов»);

Тоже самое, переменные определяются отдельно от функции:

function hello($name, $sur_name){

echo «$name $sur_name, привет!»

}

$name = «Степан»;

$sur_name = «Чельцов»;

hello($name, $sur_name);

Выдаем результат при вызове через return:

function $matem($b){

$b = $b*2;

return $b;

}

$result = matem(«10»);

Пример с массивом:

$mas10[] = «Иван»;

$mas10[] = «Иванов»;

$mas10[] = 21;

$mas10[] = «муж.»;

$mas11[] = «Иван»;

$mas11[] = «Иванов»;

$mas11[] = 21;

$mas11[] = «муж.»;

$mas12[] = «Иван»;

$mas12[] = «Иванов»;

$mas12[] = 21;

$mas12[] = «муж.»;

 

function anketa(){

foreach($array as $item){

echo «$item <br>»;

}

}

anketa(mas10);

anketa(mas11);

anketa(mas12);

Вызов значения и функций из других файлов. Вызов через include не останавливает работу страницы в случае ошибки:

include «some_function.php»;

Вызов значения и функций из других файлов. Вызов через require останавливает работу всей страницы в случае ошибки:

require «some_function.php»;

Вызов значения и функций из других файлов только один раз:

include_once «some_function.php»;

Вызов значения и функций из других файлов только один раз:

require_once «some_function.php»;

Глобальные массивы

Массив POST

Массив POST хранит данные из форм сайта в заданные файлы:

form method = «post» action = «tutor-putor.php>

<input type = «text» name = «login» value = «Логин»/><br>

<input type = «email» name = «email» value = «Почта»/><br>

<input type = «submit» name = «save» value = «Сохранить»/><br>

</form>

В файле tutor-putor.php следующее содержимое для приема и вывода данных:

<?php

$_POST[«login»];

$_POST[«email»];

?>

Чтобы защитить сайт от инъекций, начинаем чистить ввод. Сначала от html-текстов через strip_tags:

$login = strip_tags($_POST[‘login’]);

Уберем пробелы из логина через trim:

$login = strip_tags(trim($_POST[‘login’]));

Преобразуем спец.символы в их код через htmlspecialchars:

$login = htmlspecialchars(strip_tags(trim($_POST[‘login’])));

Сделаем очистку через функцию:

function clear_data($same_data){

return htmlspecialchars(strip_tags(trim($same_data)));

}

$login = clear_data($_POST[‘login’]);

$email = clear_data($_POST[’email’]);

Массив GET

Массив нужен для создания динамики на сайте. С одной стороны, можно передать данные на сервер. С другой, определить содержимое сайта в зависимости от параметра.

Чтобы передать данные можно использовать метод GET:

form method = «get» action = «tutor-putor.php>

<input type = «text» name=»login» value = «Логин»/><br>

<input type = «email» name = «email» value = «Почта»/><br>

<input type = «submit» name = «save» value = «Сохранить»/><br>

</form>

 

<?php

$_GET[«login»];

$_GET[«email»];

?>

Выдача получится через адресную строку:

http://cheltsov.ru/tutor-putor.php?login=vasya&email=vasya@gmail.com&save=Сохранить

Пример работы без предварительной подготовки через GET:

<?php

if($_GET[‘id’]==1)

echo «Пункт номер 1»;

else

echo «Другой пункт»;

?>

Переход по адресу с заданным значением:

http://cheltsov.ru/tutor-putor.php?id=1

Выдаст

Пункт номер 1

Изменим содержимое сайта в зависимости от параметра:

<?php

switch($page){

case = «main»;

$title = «Главная страница»;

$text = «Это главная страница»;

break;

case = «news»;

$title = «Страница новостей;

$text = «Это новостная страница»;

break;

default;

$title = «404 страница;

$text = «Это страница для ошибочных данных»;

break;

}

?>

<h1><?php echo $title ?></h1>

<p><?php echo $text ?></p>

http://cheltsov.ru/tutor-putor.php?page=main

Выдаст

Главная страница

Это главная страница

Массив SERVER

Массив SERVER для получения данных от сервера. Например, получение IP-адреса посетителя:

$_SERVER[‘REMOTE_ADDR’]

Или информация про браузер посетителя:

$_SERVER[‘HTTP_USER_AGENT’]

Вывод содержимого ответа сервера в явном виде:

<html>

<body>

<pre>

<?php

print_r($_SERVER);

?>

</pre>

</body>

</html>

Константы

Определяем константы через define:

<?php

define («MYNAME»,»Stepan»);

echo MYNAME;

?>

Подстановка адреса нашего сайта для указания неполного адреса при программировании:

<?php

define («BASE_URL»,»http://cheltsov.ru/»);

?>

<img src=»<?php BASE_URL;?>images/logo.png»/>

Cookies

Куки нужны для сохранения информации пользователя при работе с сайтом. Например, галочки «Запомнить меня» на разных сайтах сохраняет значение логина и пароля сохраняет файл cookies.

Чтобы создать файл cookies, надо:

<?php

setcookie(«name»,»Stepan», time()+36000);

?>

<DOCTYPE>

<html>

Чтобы вызвать вызвать значение сохраненной куки, пишем $_COOKIE[»]:

<body>

<?php

echo $_COOKIE[‘name’];

?>

</body>

</html>

Получаем:

Stepan

 

<?php

if (isset($_POST[‘send’])){

$bg = $_POST[‘bg’];

setcookie(«background»,»$bg», time()+3600);

}

?>

<DOCTYPE>

<html>

<head></head>

<body>

<?php if(isset($_COOKIE[‘background’])){?>

<style>

body

{

background:<?php echo $_COOKIE[‘background’];?>;

}

</style>

<?php }?>

<form method=»post» action=»»>

Выберите цвет фона страницы:<br>

<select name=»bg»>

<option value=»red»>Красный</value>

<option value=»black»>Черный</value>

<option value=»yellow»>Желтый</value>

</select>

<input type=»submit» name=»send» value=»Выбрать»/>

</form>

<p>В куки записан цвет <?php echo $_COOKIE[‘background’];?></p>

</body>

</html>

Чтобы удалить куку, есть способы через вывод отрицательного времени жизни куки:

setcookie(«background»,»$bg», time()-3600);

Или через обнуление данных:

setcookie(«background»,»»);

Или проще:

setcookie(«background»);

Сессии

Сессии выполняют примерно те же роли, что и куки. Разница в количестве сохраняемых данных. Куки могут сохранять немного, а сессии много. Куки хранятся долго, независимо от открытости браузера. А сессии обычно заканчиваются при закрытии браузера.

Начинаем объявление сессии:

<?php

session_start();

if (isset($_POST[‘send’])){

$_SESSION[‘name’] = strip_tags(trim($_POST[‘name’]));

}

if(!isset($_SESSION[‘name’])){

?>

<DOCTYPE>

<html>

<head></head>

<body>

<form method=»post» action=»»>

Звать как?<br>

<input type=»text» name=»name» value=»Имя»/>

<input type=»submit» name=»send» value=»Выбрать»/>

</form>

<?php }

else{

echo «Hello, «.$_SESSION[‘name’];

}

?>

</body>

</html>

Уничтожить сессию можно командой session_destroy():

session_destroy();

Частичное уничтожение сессии (отдельные данные) делаем через unset:

unset($_SESSION[‘name’]);

Подключение базы данных

Если база уже создана, с ней надо работать. Подключается база готовой функцией:

mysql_connect(«localhost»,»root»,»12345″);

mysql_select_db(«base_name»);

Красивый подход через переменные:

$connection = mysql_connect(«localhost»,»root»,»12345″);

$data_base = mysql_select_db(«base_name»);

Добавим кодировку:

mysql_set_charset(«utf8»);

Или так:

mysql_query(«SET NAMES ‘UTF8′»);

Проверим соединение:

<?php

if(!$connection || !$data_base){

exit(mysql_error());

}

else{

echo «Соединение успешно прошло»;

}

?>

После окончания работы с базой данных закрываем соединение через:

mysql_close();

Выборка из базы данных. Готовим выборку и передаем все в переменную:

$result = mysql_query(«SELECT * FROM base_name»);

mysql_close();

Создаем массив для всех полученных данных, чтобы работать с ним:

$row = mysql_fetch_array($result);

Выводим какую-нибудь ячейку из полученного массива:

echo $row[‘title’].»<br>»;

echo $row[‘text’];

Чтобы вывести все данные по строчно из базы, введем условие while:

while($row = mysql_fetch_array($result)){

echo $row[‘title’].»<br>»;

echo $row[‘text’];

}

И добавим верстки к нашему выводу данных:

<?php

while($row = mysql_fetch_array($result)){

?>

<div class=»content»>

<h2><?php echo $row[‘title’];?></h2>

<p><?php echo $row[‘text’];?></p>

</div>

<?php

}

?>

Добавим в выборку сортировку по какому-нибудь параметру. Для этого добавляем при формировании массива «ORDER BY«. Значение DESC сортирует в обратном порядке по полю id:

$result = mysql_query(«SELECT * FROM base_name ORDER BY id DESC»);

Ограничим выборку количеством выдачи, скажем только 25 результатов. Используем команду LIMIT:

$result = mysql_query(«SELECT * FROM base_name ORDER BY id DESC LIMIT 25»);

Введем фильтрацию выдачи по заданному слову через команду WHERE:

$result = mysql_query(«SELECT * FROM base_name WHERE text=’новость’ ORDER BY id DESC LIMIT 25»);

Ограничим получение данных из базы перечислением нужных колонок. Убираем * и пишем через запятую имена полей:

$result = mysql_query(«SELECT title,text FROM base_name WHERE text=’новость’ ORDER BY id DESC LIMIT 25»);

В выборку можно подставлять переменные, которые где-то определяются или вычисляются.

Как добавлять записи в бд через формы

Для соединения с базой сделаем отдельный файл подключения с содержимым, назовем его «db.php»:

<?php

$connection = mysql_connect(«localhost»,»root»,»12345″);

$data_base = mysql_select_db(«base_name»);

mysql_set_charset(«utf8»);

if(!$connection || !$data_base){

exit(mysql_error());

}

else{

echo «Соединение успешно прошло»;

}

?>

Создаем форму добавления:

<form method = «post» action = «tutor-putor.php>

<input type = «text» name = «title» value = «Заголовок»/><br>

<textarea cols=»40″ name=»text» rows=»10″ value=»Текст сообщения»><?textarea><br>

<input type = «text» name = «author» value = «Автор»/><br>

<input type = «hidden» name = «date» value = «<?php echo date(‘Y-m-d’)?>»/><br>

<input type = «hidden» name = «time» value = «<?php echo time(‘H:i:s’)?>»/><br>

<input type = «submit» name = «add» value = «Отправить»/><br>

</form>

Подключаем нашу базу через include_once:

include_once(«db.php»);

Принимаем значения из формы в переменные:

if(isset($_POST[‘add’])){

$title = strip_tags(trim($_POST[‘title’]));

$text =strip_tags(trim($_POST[‘text’]));

$author =strip_tags(trim($_POST[‘author’]));

$date =strip_tags(trim($_POST[‘date’]));

$time =strip_tags(trim($_POST[‘time’]));

Делаем запрос к базе:

mysql_query(» INSERT INTO data_base(title, text,author, date, time) VALUES (‘$title’.’$text’.’$author’.’$date’.’$time’)»);

mysql_close();

echo «Данные успешно добавлены.»;

} //закрыли if сверху

Как обновлять данные в базе

Если нам надо что-то поправить в уже введенной информации, надо ее сначала запросить на вывод.

<?php

include_once(«db.php»);

$id = $_GET[‘id’];

$result = mysql_query(«SELECT title,text,author,date,time FROM base_name WHERE id=’$id'»);

?>

Создаем цикл заполнения:

while($row = mysql_fetch_array($result)){

}

Подставляем значения в форму редактирования:

<form method = «post» action = «tutor-putor.php?id=<?php echo $id; ?>»>

<input type = «text» name = «title» value = «<?php echo $row(‘title’);?>»/><br>

<textarea cols=»40″ name=»text» rows=»10″ value=»<?php echo $row(‘text’);?>»><?textarea><br>

<input type = «text» name = «author» value = «<?php echo $row(‘author’);?>»/><br>

<input type = «submit» name = «save» value = «Изменить»/><br>

</form>

Далее в форме мы редактируем данные, если необходимо. Чтобы данные сохранились, надо сделать:

if(isset($_POST[‘save’])){

$title = strip_tags(trim($_POST[‘title’]));

$text =strip_tags(trim($_POST[‘text’]));

$author =strip_tags(trim($_POST[‘author’]));

mysql_query(» UPDATE data_base SET title=», text=»,author=» WHERE id=’$id'»);

mysql_close();

echo «Данные успешно обновлены.»;

}

Удаление записей из базы данных

Повторяем ту же конструкцию, только меняем запрос к базе:

<?php

include_once(«db.php»);

$id = $_GET[‘id’];

mysql_query(«DELETE FROM base_name WHERE id=’$id’ «);

mysql_close();

echo «Данные успешно удалены.»;

?>

Адаптив для любой диагонали экрана

Новый день с программированием и CSS

Как я уже рассказывал, мои взгляды на программирование недавно изменились после знакомства с каналом Михаила Базарова:

https://www.youtube.com/channel/UCTlFw1VKSOwxkBIyETv7sFA

Сначала я смотрел и думал, подтягивал знания верстки. А сегодня решил начать действовать.

Позавчера я научился ставить виртуальный сервер на своем маке, научился работать через Atom и Sftp-плагин для хрома. И сегодня я начал верстать новый магазин подарков.

У меня есть ряд претензий к текущему магазину, которые я не хочу давать на исправление другим. Я хочу сам сверстать новый шаблон, чтобы прочувствовать все проблемы на себе. При этом я хочу убедиться, что я все выполнил правильно.

Список претензий:

  • Меню сверху слишком много сжирает места, целых 230 пикселей;
  • Старая шапка сайта www.thepresents.ru

    Старая шапка сайта www.thepresents.ru

  • Меню снизу занимает 3 экрана. Целых 3 бесполезных экрана, которые непонятно зачем там находятся.

    Старый футер №1 сайта www.thepresents.ru

    Старый футер №1 сайта www.thepresents.ru

    Старый футер №2 сайта www.thepresents.ru

    Старый футер №2 сайта www.thepresents.ru

    Старый футер №3 сайта www.thepresents.ru

    Старый футер №3 сайта www.thepresents.ru

  • В меню будут добавлены пункты, которые определят индивидуальный подход к покупателю;
  • На разных страницах будет работать встроенный функционал битрикса, который сейчас у меня не работает по ряду причин кастомной разработки;
  • Невозможность быстро и красиво менять дизайн по необходимости;

Под словом «правильно» я подразумеваю безопасную верстку и модульную разработку. Такая правильность обеспечивает безопасность при обновлении ядра битрикса или иных модулей. Как только у нас идет разработка по модулям, риски значительно снижаются, а разработка упрощается. Так мне кажется.

Ниже представляю скрины своих наработок за сегодня и зачатки будущего дизайна. Один из принципов, которые я хочу заложить — адаптивность не только под маленькие экраны телефонов, но и под большие экраны высокого разрешения.

Так же я решил убрать картинки, которые можно делать силами CSS. Первой жертвой стала плашка разделитель:

Старый градиент сайта www.thepresents.ru

Старый градиент сайта www.thepresents.ru

Я заменил ее тегом <div> и свойством класса:

.line_gradient {

display:block;

float: center;

font-size:1px;

width:100%;

height: 5%;

background-image: linear-gradient(to right, #FFD700, #9400D3, #000000, #9400D3, #000000, #00FFFF, #00008B);

}

Новый градиент www.thepresents.ru

Новый градиент www.thepresents.ru

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

Как изменять размер шрифта в зависимости от разрешения экрана?

Соответственно мне стало интересно, как заставить шрифты изменяться в зависимости от разрешения экрана. И гугление проблемы мне помогло найти новые типы измерения:

1vw = 1% от ширины области просмотра

1vh = 1% от высоты области просмотра

1vmin = 1vw или 1vh, берется наименьшее значение

Теперь у меня такие настройки для футера:

.footer {

width:100%;

min-height:7%;

/*background: url(’images/footer_bg.jpg’);*/

background-color: #2F4F4F; /*#2F4F4F, #000000, #006400, #000000, #2F4F4F, #008080)*/;

position: absolute;

bottom: 0px;

}

.line_gradient {

width:100%;

height: 7%;

background-image: linear-gradient(to right, #FFD700, #9400D3, #000000, #9400D3, #000000, #00FFFF, #00008B);

position:absolute;

}

.container_footer {

width:100%;

position: top;

display: inline-block;

vertical-align: middle;

text-align: center;

font-size: 4vw;

font-size: 4vh;

font-size: 3vmin;

color: #ffffff;

padding: 0.3% 0% 0.001% 0%;

}

.copyright_store {

max-width:25%;

margin: 1% 0% 1% 8%;

float:left;

}

.email_spam {

max-width:25%;

margin: 2% 0% 1% 3%;

float:left;

}

.email_spam a {

color: #FF8C00;

}

.rights_dev {

max-width:25%;

margin: 1% 8% 1% 3%;

float:right;

}

.rights_dev span a {

color: #FF8C00;

}

Результат моей работы теперь виден на видео. Меняю масштаб, диагональ экрана, информация остается читаемой.

Новый дизайн www.thepresents.ru

Новый дизайн www.thepresents.ru

Полуночная верстка для сна

Вечерами и ночами на этой и прошлой неделе я писал строки технического задания на разработку важного внутреннего проекта. Строк выходило много, потому что я занудно описывал каждое поле, кнопочку, варианты изменения интерфейсов и прочие штуки-дрюки с правами доступов. Помимо описания я еще и рисовал эти самые интерфейсы.

Так как мозг на это дело изрядно напрягался, надо было расслабляться. И нет ничего лучше на текущий момент, чем разобраться в вопросах верстки. Я прошел два курса «Блочная модель документа» и «Позиционирование» в полубессонном состоянии, и пытался разобраться с LESS. Хочу вас рассказать краткие выводы:

  • верстка — по-прежнему увлекательное дело;
  • каждый html-файл мне теперь представляется более логичным;
  • благодаря изучению, я понял, что и как хочу изменить на своем Магазине подарков;
  • первые шаги я уже реализовал через оформление карточки товара в магазине, увеличив шрифты, изменив поток документа и межстрочные интервалы;
  • я задался целью научиться разворачивать локальный сервер на своем макбуке, чтобы проводить эксперименты у себя, а выгружать удачные на сервер. Расскажу об этом в следующий раз.

У меня остается куча вопросов, которые буду когда-нибудь изучать без спешки:

  • Разобраться с java-script;
  • Разобраться с php;
  • Разобраться с Go;
  • Разобраться с вносом данных в базу данных и их извлечением.

Хватит питонить, будем css-ить

Увы и ах.

Программирование мне до конца марта не юзать. Просто потому, что дел сейчас слишком много, а поверхностно изучать смысла нет.

Потому переключаюсь более легкое для восприятия — CSS. Это про верстку сайтов, оформление и все прочее, называемое фронтендом.

Помогает мне в этом прекрасный ресурс www.htmlacademy.ru, курсы которых я начал изучать благодаря прекрасной д.

Новый день с Питоном

Продолжаем знакомство с Питоном.

Вы наверное давно ушли вперед меня, потому я решил нагонять все через видео. Сегодня я посвятил время пониманию и различию глобальных и локальных переменных. Глобальные — используемые во всей программе. А локальные — только внутри функций и для других функций. Одно и тоже имя переменной может быть и в локальной и в глобальной части. И Питон четко понимает, где какая из-за последовательности их применения. Это для понимания сложнова-то, потому я не переусердствовал, понимая только это. Остальное время посвятил изучению блочной верстки в HTMLAcademy.

И все, что я сегодня смог, это повторять штуки с этого видео:

Таким образом мы с вами осваиваем взаимодействие двух функций между собой. Значений и условия в одном используются в другом и дают один результат. И научился разделять глобальные и локальные

Учимся понимать функции на Питоне

На этой неделе мы узнали про Питон следующее из 3 главы официального самоучителя:

https://automatetheboringstuff.com/chapter3/

  1. Функция — это набор правил, которые надо выполнить. Например, сделать функцию, которая выводит слово «Привет!», и больше ничего не делает. Или можно сделать функцию, которая обращается к серверу, запрашивает данные и выдает не «Привет!», а таблицу с данными из базы. Важно запомнить, что все программировании завязано на функции;
  2. Скорость выполнения функции зависит от е сложности. Пока мы не очень разбираемся, лучше делать много простых функций, чем одну супер сложную. А когда функций много, с ними проще разбираться новичку и проверяющему;
  3. Функция в Питоне начинается с термина def. То, что следует за def, называется именем функции. Например, def hello() будет означать наличие функции «hello»;
  4. Имя нужно функции для того, чтобы вызывать ее в разных частях кода. Тоесть мы не будем везде и всюду вставлять код функции, а просто вставим Hello(), а на выходе будет результат работы этой функции;
  5. Если изменить функцию, она изменится сразу во всей программе, если мы указывали ее по имени;
  6. Все строки, которые идут за именем функции — тело функции. Все что вы там напишете, будет выполняться и выводиться каждый раз, когда будет вызываться функция;
  7. В скобках у имени функции задается параметр, который будет работать с функцией. Например, мы выводим функцию def hello(name), а в теле пишем вывод сообщения print (’Hello «+ name +»!«). Теперь в нужных нам местах кода пишем имя функции с нужным параметром, например, hello(Stepan). При запуске программы при запуске функции мы получим ответ от функции «Hello Stepan!»;
  8. Важно запомнить, что если мы используем один параметр для функции, то в другом месте может быть любой другой параметр, или он может быть результатом работы другой функции. Такой бесконечный вложенный цикл может получиться;
  9. Ответ функции на официальном языке называется «возвращенное значение». Мы кинули функции задачу, она вернула ответ;
  10. Все простые текстовые сообщения помещаются в одинарные кавычки ’’, тоесть хотим вставить красное словцо, пишем его так:’Красное словцо’;
  11. Очень сложно для понимания новичку научиться читать код. Например, вот код на вывод значения функции из примера print(getAnswer(random.randint(1, 9))). Читать ее следует так: выведи результат функции gerAnswer для случайного числа в диапазоне от 1 до 9. А за этой простой фразой стоит большая функция и всякие выражения из примера;

На этом на этой неделе хватит, хорошего по немножку.

Отступы документа в Excel через макрос VBA Visual Basic

Макрос для изменения отступов в документе excel на Листе, на котором запущен макрос. Регулирование отступов происходит через значения в скобках. Мои стандартные параметры ниже:

Sub Macros

With ActiveSheet.PageSetup
.LeftMargin = Application.InchesToPoints(0.2)
.RightMargin = Application.InchesToPoints(0.2)
.TopMargin = Application.InchesToPoints(0.4)
.BottomMargin = Application.InchesToPoints(0.4)
.HeaderMargin = Application.InchesToPoints(0.1)
.FooterMargin = Application.InchesToPoints(0.1)
End With
End Sub

Можно дополнить им любой макрос или оставить самостоятельным.

Простейший склад через Гугл.Формы

Склад и складские функции — основа любой торговли. Товары поступают на склад, и уходят с него. Поступления и списания бывают разных типов. Например, поступление может быть нового товара от поставщика или возврат брака. А списания со склада могут быть продажей клиентам, списанием брака, списанием просроченного товара, и просто перемещение на другой склад. Как же все это контролировать онлайн несколькими операторами?

Есть множество складских программ: 1С, Мой склад, Антисклад, Купеческая книга, Vast и куча других. Но все они сложные и обладают очень большим функционалом, который нам не нужен. Ну разве что Vast почти то, что нужно, но всеравно неудобен и глючит.

Сделаем самую простую модель складского учета в Гугл.Документах

Сначала зайдем в Гугл.Документ и создадим форму. В ней мы укажем только одно значение: Наименования с типом ответов «Один из списка», сотрем демо данные «Вариант 1» и нажмем на кнопку «Другое», чтобы быстро вводить нужные нам новые наименования.

Как зайти в Гугл.Формы

Как зайти в Гугл.Формы

Немного заполним эту таблицу и откроем ответы. Как видите, все так, как мы делали. Кстати, бывает глюк. Если не отметить радиокнопку, данные не введутся. Так бывает. Переименуем нашу вкладку в «Наименования».

Наименования товаров

Наименования товаров

Теперь откром пункт меню Инструменты и создадим еще одну форму. В ней уже начнем вводить нужные для склада пункты: Наименования, Количество, Тип операции. В каждом пункте стираем демо данные и в «Количество» выставляем «Другое».

Форма для склада

Форма для склада

Ввод наименований в гугл.форму

Ввод наименований в гугл.форму

Теперь зайдем в Дополнения и установим модуль rangeForm, запустим его и для Наименований выберем наш документ и вкладку «Наименования», которые мы делали до этого. Теперь все новые наименования через первую форму будут автоматически попадать в эту форму. Не забудь в нижней части дополнения активировать модуль на постоянной основе.

Наименования товаров из вкладки

Наименования товаров из вкладки

Заполним немного таблицу приходами и расходами. Помним, что мы тренируемся и это упрощенная модель.

Вернемся к нашим ответам. Там все именно так, как мы вводили, только что с этим делать? Давайте немного дополним данные.

Во-первых, надо переименовать вкладку, например, в «Журнал», потому что это просто поток операций, который мы записали. Во-вторых, нам нужно всем операциям «Расход» сделать отрицательные значения. Добавим колонку и сделаем введем простую формулу =if(C2=»Расход»;D2*(-1);D2), протянем ее по всему интервалу наших значений. Эту новую колонку назовем Поток, просто для внутреннего настроя на поток товаров на склад и со склада.

Заполненный журнал данными

Заполненный журнал данными

Теперь нам надо установить дополнение под названием copyDown, которое делает одну очень важную вещь — при очередной заполнении формы этот плагин скопирует наши формулы на этом листе вниз. Бага этого плагина является его фичей — он работает только на первой вкладке, на прочих не работает.

Работа модуля по добавлению формул

Работа модуля по добавлению формул

Чтобы понять, что там у нас происходило со складом, предлагаю сделать Сводные таблицы, которые находятся во вкладке Данные. Справа появляется странное окно. Давайте выберем в нем такую последовательность:

  • В строки выберем Наименования;
  • В столбцы Тип операции;
  • В значения ставим Количество и выставляем тип математики SUM;
  • Фильтры оставляем пустыми.
Состояние склада через сводную таблицу

Состояние склада через сводную таблицу

Получаем красивую таблицу с итоговыми данными, которыми можно оперативно пользоваться. А если зайти в Форма и выбрать Сводка ответов, то можно даже динамику прослеживать без особых усилий.

P.S. Так как идея изначально была только в показе принципа, то надо понимать некоторые допущения:

  1. Мы сначала должны оприходовать фактические товары, а потом их расходовать по факту выдачи;
  2. Если у нас отрицательный баланс, значит кто-то невнимательно работал с формой, и это видно в истории изменений.

Надеюсь, этот пост был вам полезен. Следом я сделаю более сложную форму для работы со складом.

Работа с Гугл.Документами через Питон

Должен признаться, что перейти от простых функций к сложным — очень не просто. Тоесть можно легко понять сложения и вычитания, умножения, присвоение значений друг другу, но вот начать все это превращать во что-то ценное и полезное.

На этой неделе я мало посвящал времени программированию ровно потому, что не знал, какую бы работу мне автоматизировать. И сегодня я понял, что и как мне нужно.

У меня возникла необходимость ведения простейшего складского учета: приемка оборудования, выдача разным людям, анализ того, что кому было выдано. Думаете, это легко найти в готовых облачных хранилищах? Вы ошибаетесь — никто нормального ничего не сделал. Все решения супер сложные, неудобные и тошнотворные. Миллион нажатий кнопок, миллион ненужных значений вокруг, а надо всего-навсего вести учет 20 наименований.

Я сделал в Гугл.Документах файл с приходами и расходами, научился все увязывать между собой в рамках одного документа, кучи вкладок и даже сделал динамически меняющиеся формы. Просто представьте — управление складом через формы Гугла! Классно звучит. Но появилась одна проблема, которую я и буду теперь решать.

Проблема заключается в том, что добавление нового значения через форму приводить к добавлению новой строки, а значит надо протягивать формулы каждый раз, как произошло добавление данных. Вторая часть проблемы — динамическое обновление скриптов, который работают с формами Гугла. Мне нужно обновление сразу, а не через несколько минут.

Для решения этой задачи я начинаю смотреть вот эти данные по работе с Гугл.Документами по API через Питон:

https://developers.google.com/apps-script/guides/rest/quickstart/python

А как это будет происходить — читайте на следующей неделе.