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

Работает с ORM D7 и выкинет эксепшн, если не сможет довести дело до конца. Поэтому готовить, её надо с более-менее свежими битриксами (>14 версии).

<?php
/**
 * Created by olegpro.ru.
 * User: Oleg Maksimenko <oleg.39style@gmail.com>
 * Date: 28.05.2016 13:57
 */
 
namespace Olegpro\Helpers;
 
use Bitrix\Iblock\PropertyEnumerationTable;
use Bitrix\Iblock\PropertyTable;
use Bitrix\Main\SystemException;
use CIBlockPropertyEnum;
 
class IblockProperty
{
 
    /**
     * @param $value
     * @param $iblockId
     * @param $propertyCode
     * @return int
     * @throws SystemException
     * @throws \Bitrix\Main\ArgumentException
     */
    public static function getEnumId($value, $iblockId, $propertyCode)
    {
        static $cacheProperties = [];
 
        static $cachePropertiesEnumerationValues = [];
 
        $property = null;
 
        $propertiesEnumeration = null;
 
        if (!isset($cacheProperties[$iblockId . '|' . $propertyCode])) {
 
            $propertyIterator = PropertyTable::getList([
                'select' => [
                    'ID',
                    'PROPERTY_TYPE',
                ],
                'filter' => [
                    '=IBLOCK_ID' => $iblockId,
                    '=CODE' => $propertyCode,
                ]
            ]);
 
            if ($propertyData = $propertyIterator->fetch()) {
                if ($propertyData['PROPERTY_TYPE'] != PropertyTable::TYPE_LIST) {
                    throw new SystemException(sprintf('Property "%s" not list type.', $propertyCode));
                }
 
                $property = $cacheProperties[$iblockId . '|' . $propertyCode] = $propertyData;
            }
 
        } else {
            $property = $cacheProperties[$iblockId . '|' . $propertyCode];
        }
 
        $preparedValue = ToLower(trim($value));
 
        if (!isset($cachePropertiesEnumerationValues[$iblockId . '|' . $propertyCode . '|' . $preparedValue])) {
            $propertiesEnumerationIterator = PropertyEnumerationTable::getList([
                'select' => [
                    'ID',
                ],
                'filter' => [
                    '=PROPERTY_ID' => $property['ID'],
                    '=VALUE' => $value,
                ]
            ]);
 
            if ($propertiesEnumerationData = $propertiesEnumerationIterator->fetch()) {
                $propertiesEnumeration = $cachePropertiesEnumerationValues[$iblockId . '|' . $propertyCode . '|' . $preparedValue]
                    = $propertiesEnumerationData;
            } else {
                // Old school api for generate XML_ID, clear cache, etc..
                $propertiesEnumerationNewId = CIBlockPropertyEnum::Add([
                    'VALUE' => $value,
                    'PROPERTY_ID' => $property['ID'],
                ]);
 
                if ($propertiesEnumerationNewId <= 0) {
                    throw new SystemException(sprintf('Error add property enumeration value "%s" not list type.', $value));
                } else {
                    $propertiesEnumeration = $cachePropertiesEnumerationValues[$iblockId . '|' . $propertyCode . '|' . $preparedValue]
                        = [
                        'ID' => $propertiesEnumerationNewId,
                    ];
                }
            }
        } else {
            $propertiesEnumeration = $cachePropertiesEnumerationValues[$iblockId . '|' . $propertyCode . '|' . $preparedValue];
        }
 
        return (int)$propertiesEnumeration['ID'];
 
    }
 
}